Skip to content

Commit 013950f

Browse files
authored
fix(cli): avoid CLI loading env var too early with code cleanup (#422)
1 parent 894e84f commit 013950f

File tree

2 files changed

+36
-15
lines changed

2 files changed

+36
-15
lines changed

python/cocoindex/cli.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
from rich.console import Console
55

66
from . import flow, lib, setting
7-
from .flow import flow_names
87
from .setup import sync_setup, drop_setup, flow_names_with_setup, apply_setup_changes
98
from .runtime import execution_context
109

@@ -22,7 +21,7 @@ def ls(show_all: bool):
2221
"""
2322
List all flows.
2423
"""
25-
current_flow_names = flow_names()
24+
current_flow_names = flow.flow_names()
2625
persisted_flow_names = flow_names_with_setup()
2726
remaining_persisted_flow_names = set(persisted_flow_names)
2827

@@ -150,47 +149,54 @@ def evaluate(flow_name: str | None, output_dir: str | None, cache: bool = True):
150149
options = flow.EvaluateAndDumpOptions(output_dir=output_dir, use_cache=cache)
151150
fl.evaluate_and_dump(options)
152151

153-
_default_server_settings = setting.ServerSettings.from_env()
154-
152+
# Create ServerSettings lazily upon first call, as environment variables may be loaded from files, etc.
155153
COCOINDEX_HOST = 'https://cocoindex.io'
156154

157155
@cli.command()
158156
@click.option(
159-
"-a", "--address", type=str, default=_default_server_settings.address,
160-
help="The address to bind the server to, in the format of IP:PORT.")
157+
"-a", "--address", type=str,
158+
help="The address to bind the server to, in the format of IP:PORT. "
159+
"If unspecified, the address specified in COCOINDEX_SERVER_ADDRESS will be used.")
161160
@click.option(
162161
"-c", "--cors-origin", type=str,
163-
default=_default_server_settings.cors_origins and ','.join(_default_server_settings.cors_origins),
164162
help="The origins of the clients (e.g. CocoInsight UI) to allow CORS from. "
165163
"Multiple origins can be specified as a comma-separated list. "
166-
"e.g. `https://cocoindex.io,http://localhost:3000`")
164+
"e.g. `https://cocoindex.io,http://localhost:3000`. "
165+
"Origins specified in COCOINDEX_SERVER_CORS_ORIGINS will also be included.")
167166
@click.option(
168167
"-ci", "--cors-cocoindex", is_flag=True, show_default=True, default=False,
169168
help=f"Allow {COCOINDEX_HOST} to access the server.")
170169
@click.option(
171170
"-cl", "--cors-local", type=int,
172-
help=f"Allow http://localhost:<port> to access the server.")
171+
help="Allow http://localhost:<port> to access the server.")
173172
@click.option(
174173
"-L", "--live-update", is_flag=True, show_default=True, default=False,
175174
help="Continuously watch changes from data sources and apply to the target index.")
176175
@click.option(
177176
"-q", "--quiet", is_flag=True, show_default=True, default=False,
178177
help="Avoid printing anything to the standard output, e.g. statistics.")
179-
def server(address: str, live_update: bool, quiet: bool, cors_origin: str | None,
178+
def server(address: str | None, live_update: bool, quiet: bool, cors_origin: str | None,
180179
cors_cocoindex: bool, cors_local: int | None):
181180
"""
182181
Start a HTTP server providing REST APIs.
183182
184183
It will allow tools like CocoInsight to access the server.
185184
"""
186-
cors_origins : set[str] = set()
185+
server_settings = setting.ServerSettings.from_env()
186+
cors_origins: set[str] = set(server_settings.cors_origins or [])
187187
if cors_origin is not None:
188-
cors_origins.update(s for o in cors_origin.split(',') if (s:= o.strip()) != '')
188+
cors_origins.update(setting.ServerSettings.parse_cors_origins(cors_origin))
189189
if cors_cocoindex:
190190
cors_origins.add(COCOINDEX_HOST)
191191
if cors_local is not None:
192192
cors_origins.add(f"http://localhost:{cors_local}")
193-
lib.start_server(setting.ServerSettings(address=address, cors_origins=list(cors_origins)))
193+
server_settings.cors_origins = list(cors_origins)
194+
195+
if address is not None:
196+
server_settings.address = address
197+
198+
lib.start_server(server_settings)
199+
194200
if live_update:
195201
options = flow.FlowLiveUpdaterOptions(live_mode=True, print_stats=not quiet)
196202
execution_context.run(flow.update_all_flows(options))

python/cocoindex/setting.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"""
44
import os
55

6-
from typing import Callable, Self, Any
6+
from typing import Callable, Self, Any, overload
77
from dataclasses import dataclass
88

99

@@ -58,5 +58,20 @@ def from_env(cls) -> Self:
5858
kwargs: dict[str, Any] = dict()
5959
_load_field(kwargs, "address", "COCOINDEX_SERVER_ADDRESS")
6060
_load_field(kwargs, "cors_origins", "COCOINDEX_SERVER_CORS_ORIGINS",
61-
parse=lambda s: [o for e in s.split(",") if (o := e.strip()) != ""])
61+
parse=ServerSettings.parse_cors_origins)
6262
return cls(**kwargs)
63+
64+
@overload
65+
@staticmethod
66+
def parse_cors_origins(s: str) -> list[str]: ...
67+
68+
@overload
69+
@staticmethod
70+
def parse_cors_origins(s: str | None) -> list[str] | None: ...
71+
72+
@staticmethod
73+
def parse_cors_origins(s):
74+
"""
75+
Parse the CORS origins from a string.
76+
"""
77+
return [o for e in s.split(",") if (o := e.strip()) != ""] if s is not None else None

0 commit comments

Comments
 (0)