Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions dev/generate_cli_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ def escape_html_tags(text: str) -> str:

return "".join(result)


def format_options_section(help_text: str) -> str:
"""Extract and format the options section."""
lines = help_text.split("\n")
Expand Down Expand Up @@ -185,7 +184,9 @@ def extract_description(help_text: str) -> str:
elif in_description and line.strip():
description_lines.append(line.strip())

description = "\n\n".join(description_lines) if description_lines else ""
# Collapse multiple blank lines into a single blank line
description = "\n".join(description_lines) if description_lines else ""
description = re.sub(r"\n{3,}", "\n\n", description)
return escape_html_tags(description) # Escape HTML tags for MDX compatibility


Expand Down
73 changes: 32 additions & 41 deletions python/cocoindex/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def _get_app_ref_from_specifier(
specifier: str,
) -> str:
"""
Parses the APP_TARGET to get the application reference (path or module).
Parses the `APP_TARGET` to get the application reference (path or module).
Issues a warning if a flow name component is also provided in it.
"""
app_ref, flow_ref = _parse_app_flow_specifier(specifier)
Expand All @@ -84,7 +84,7 @@ def _load_user_app(app_target: str) -> None:
load_user_app(app_target)
except UserAppLoaderError as e:
raise click.ClickException(
f"Failed to load APP_TARGET '{app_target}': {e}"
f"Failed to load `APP_TARGET` '{app_target}': {e}"
) from e

add_user_app(app_target)
Expand Down Expand Up @@ -137,11 +137,8 @@ def ls(app_target: str | None) -> None:
"""
List all flows.

If APP_TARGET (path/to/app.py or a module) is provided, lists flows
defined in the app and their backend setup status.

If APP_TARGET is omitted, lists all flows that have a persisted
setup in the backend.
If `APP_TARGET` (`path/to/app.py` or a module) is provided, lists flows defined in the app and their backend setup status.
If `APP_TARGET` is omitted, lists all flows that have a persisted setup in the backend.
"""
persisted_flow_names = flow_names_with_setup()
if app_target:
Expand Down Expand Up @@ -188,17 +185,15 @@ def ls(app_target: str | None) -> None:
def show(app_flow_specifier: str, color: bool, verbose: bool) -> None:
"""
Show the flow spec and schema.

APP_FLOW_SPECIFIER: Specifies the application and optionally the target flow.
`APP_FLOW_SPECIFIER`: Specifies the application and optionally the target flow.
Can be one of the following formats:

\b
- path/to/your_app.py
- an_installed.module_name
- path/to/your_app.py:SpecificFlowName
- an_installed.module_name:SpecificFlowName

:SpecificFlowName can be omitted only if the application defines a single flow.
- `path/to/your_app.py`
- `an_installed.module_name`
- `path/to/your_app.py:SpecificFlowName`
- `an_installed.module_name:SpecificFlowName`
`:SpecificFlowName` can be omitted only if the application defines a single flow.
"""
app_ref, flow_ref = _parse_app_flow_specifier(app_flow_specifier)
_load_user_app(app_ref)
Expand All @@ -223,7 +218,7 @@ def show(app_flow_specifier: str, color: bool, verbose: bool) -> None:
def _drop_flows(flows: Iterable[flow.Flow], force: bool = False) -> None:
"""
Helper function to drop flows without user interaction.
Used internally by --reset flag
Used internally by `--reset` flag.

Args:
flows: Iterable of Flow objects to drop
Expand Down Expand Up @@ -297,18 +292,18 @@ async def _update_all_flows_with_hint_async(
is_flag=True,
show_default=True,
default=False,
help="Drop existing setup before running setup (equivalent to running 'cocoindex drop' first).",
help="Drop existing setup before running setup (equivalent to running `cocoindex drop` first).",
)
def setup(app_target: str, force: bool, reset: bool) -> None:
"""
Check and apply backend setup changes for flows, including the internal storage and target (to export to).

APP_TARGET: path/to/app.py or installed_module.
`APP_TARGET`: `path/to/app.py` or `installed_module`.
"""
app_ref = _get_app_ref_from_specifier(app_target)
_load_user_app(app_ref)

# If --reset is specified, drop existing setup first
# If `--reset` is specified, drop existing setup first
if reset:
_drop_flows(flow.flows().values(), force=force)

Expand All @@ -329,7 +324,6 @@ def setup(app_target: str, force: bool, reset: bool) -> None:
def drop(app_target: str | None, flow_name: tuple[str, ...], force: bool) -> None:
"""
Drop the backend setup for flows.

\b
Modes of operation:
1. Drop all flows defined in an app: `cocoindex drop <APP_TARGET>`
Expand All @@ -339,8 +333,7 @@ def drop(app_target: str | None, flow_name: tuple[str, ...], force: bool) -> Non

if not app_target:
raise click.UsageError(
"Missing arguments. You must either provide an APP_TARGET (to target app-specific flows) "
"or use the --all flag."
"Missing arguments. You must either provide an `APP_TARGET` (to target app-specific flows) or use the `--all` flag."
)

app_ref = _get_app_ref_from_specifier(app_target)
Expand Down Expand Up @@ -415,7 +408,7 @@ def drop(app_target: str | None, flow_name: tuple[str, ...], force: bool) -> Non
is_flag=True,
show_default=True,
default=False,
help="Drop existing setup before updating (equivalent to running 'cocoindex drop' first).",
help="Drop existing setup before updating (equivalent to running `cocoindex drop` first).",
)
@click.option(
"-f",
Expand Down Expand Up @@ -445,13 +438,13 @@ def update(
"""
Update the index to reflect the latest data from data sources.

APP_FLOW_SPECIFIER: path/to/app.py, module, path/to/app.py:FlowName, or module:FlowName.
If :FlowName is omitted, updates all flows.
`APP_FLOW_SPECIFIER`: `path/to/app.py`, `module`, `path/to/app.py:FlowName`, or `module:FlowName`.
If `:FlowName` is omitted, updates all flows.
"""
app_ref, flow_name = _parse_app_flow_specifier(app_flow_specifier)
_load_user_app(app_ref)

# If --reset is specified, drop existing setup first
# If `--reset` is specified, drop existing setup first
if reset:
if flow_name:
# Reset specific flow only
Expand Down Expand Up @@ -513,16 +506,14 @@ def evaluate(

Instead of updating the index, it dumps what should be indexed to files.
Mainly used for evaluation purpose.

\b
APP_FLOW_SPECIFIER: Specifies the application and optionally the target flow.
`APP_FLOW_SPECIFIER`: Specifies the application and optionally the target flow.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the \b needs to be kept, otherwise these bulleted lines below will be rewrapped.

https://click.palletsprojects.com/en/stable/documentation/#escaping-click-s-wrapping

(or did you see otherwise when running --help?)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added \b wherever required

Can be one of the following formats:
- path/to/your_app.py
- an_installed.module_name
- path/to/your_app.py:SpecificFlowName
- an_installed.module_name:SpecificFlowName

:SpecificFlowName can be omitted only if the application defines a single flow.
- `path/to/your_app.py`
- `an_installed.module_name`
- `path/to/your_app.py:SpecificFlowName`
- `an_installed.module_name:SpecificFlowName`
`:SpecificFlowName` can be omitted only if the application defines a single flow.
"""
app_ref, flow_ref = _parse_app_flow_specifier(app_flow_specifier)
_load_user_app(app_ref)
Expand All @@ -541,7 +532,7 @@ def evaluate(
"--address",
type=str,
help="The address to bind the server to, in the format of IP:PORT. "
"If unspecified, the address specified in COCOINDEX_SERVER_ADDRESS will be used.",
"If unspecified, the address specified in `COCOINDEX_SERVER_ADDRESS` will be used.",
)
@click.option(
"-c",
Expand All @@ -550,7 +541,7 @@ def evaluate(
help="The origins of the clients (e.g. CocoInsight UI) to allow CORS from. "
"Multiple origins can be specified as a comma-separated list. "
"e.g. `https://cocoindex.io,http://localhost:3000`. "
"Origins specified in COCOINDEX_SERVER_CORS_ORIGINS will also be included.",
"Origins specified in `COCOINDEX_SERVER_CORS_ORIGINS` will also be included.",
)
@click.option(
"-ci",
Expand All @@ -564,7 +555,7 @@ def evaluate(
"-cl",
"--cors-local",
type=int,
help="Allow http://localhost:<port> to access the server.",
help="Allow `http://localhost:<port>` to access the server.",
)
@click.option(
"-L",
Expand All @@ -586,7 +577,7 @@ def evaluate(
is_flag=True,
show_default=True,
default=False,
help="Drop existing setup before starting server (equivalent to running 'cocoindex drop' first).",
help="Drop existing setup before starting server (equivalent to running `cocoindex drop` first).",
)
@click.option(
"--reexport",
Expand Down Expand Up @@ -638,7 +629,7 @@ def server(

It will allow tools like CocoInsight to access the server.

APP_TARGET: path/to/app.py or installed_module.
`APP_TARGET`: `path/to/app.py` or `installed_module`.
"""
app_ref = _get_app_ref_from_specifier(app_target)
args = (
Expand Down Expand Up @@ -726,7 +717,7 @@ def _run_server(
)
raise click.Abort()

# If --reset is specified, drop existing setup first
# If `--reset` is specified, drop existing setup first
if run_reset:
_drop_flows(flow.flows().values(), force=force)

Expand Down
Loading