Skip to content

Commit ee068bf

Browse files
timzsuclaude
andauthored
refactor: remove dead ops, legacy env paths, unused deps (#2)
* refactor: remove dead ops, legacy env paths, unused deps Comprehensive sweep: - Drop unsupported graph/runtime operators: SwitchOp, MergeOp, EnterOp, ExitOp, FutureOp, CacheFetchOp, LLMCompletionOp, AppendMessageOp, LastMessageOp + their factories, registry entries, runtime dispatch branches, and the orphan runtime/functional/ module (zero importers). - Strip dead helpers: deploy.shell.host_ip, cli.core.logging.get_level/ set_level, HttpClient.put/patch/delete, BaseClient/BaseAsyncClient put/patch/delete, utils.io_locations.write_output_location and its internal DB/S3 write helpers, schemas.worker.WorkerElasticStateResponse and HardwareUsage. - Clean legacy env paths: delete .env.template duplicate; drop the S3_CERT_LOCATION alias and migrate readers to S3_CERT_FILE; remove dead envs.py bindings (S3_PUBLIC_DATA_PREFIX, LUMILAKE_TIMEOUT, LUMILAKE_BASE_URL); update README and error message to point at .env.example. - Drop unused server-extra deps: backoff, cachetools, sqlglot, tabulate (+ types-cachetools); refresh uv.lock and bump urllib3 to 2.7.0 to clear pip-audit CVEs. - CI: replace stale .gitleaksignore with a .gitleaks.toml regex allowlist for envs.S3_* config reads; add commit-message.prefix "build" + scope to dependabot.yml so its PR titles satisfy check_pr_title. Verified: 237 tests pass, pre-commit clean (isort/black/ruff/codespell/ mypy), pip-audit clean, gitleaks clean, registry trimmed to 12 live ops. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Zhengyuan Su <su.zhengyuan@u.nus.edu> * chore: drop repo-local agent_space + obsolete gitleaks allowlist - AGENTS.md: drop the agent_space/ pointer; the rule is now just "never commit throwaway scripts / experiments". - pyproject.toml: drop "agent_space" from the Ruff exclude list. - Delete .gitleaks.toml. CI scans with --no-git (.github/workflows/security.yml:49) and the working tree passes Gitleaks without any allowlist; the allowlist also referenced envs.S3_SECRET_KEY, a legacy name no longer present in source. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Zhengyuan Su <su.zhengyuan@u.nus.edu> * refactor: drop more zero-callsite functions (round 2) Comprehensive sweep round 2 — every function below has zero callers outside its own definition file (verified via grep across src/, tests/, and examples/). Medium (definitions only, no callsites): - graphs/utils.py:partition_op — delete the file. Cascades into ops/util_ops.py:SliceOp/ConcatOp + slice_op/concat factories (which were only used by partition_op) and their entries in ops/__init__.py. - runtime/runtime_graph.py:_build_sql_template — also strips the helpers it was the sole consumer of: _quote_column_ref, _quote_table_ref, _quote_identifier, _sql_param_label, _decode_ref_token, and the REF_TOKEN_PREFIX constant. - runtime/server.py:_workflow_graph_merge_signature - runtime/server.py:_parent_workflow_id_for_group - runtime/runtime_manager/flowmesh.py: _validate_shard_intent_cardinality_contract, _promote_shard_dependencies - server/routes/jobs.py:_serialize_output_locations Low (definitions only, no production callsites): - deploy/docker_client.py:container_remove - deploy/shell.py:run_output - utils/utils.py:indices_to_list - utils/parsing.py:parse_bool, build_database_url 237 tests still pass; pre-commit clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Zhengyuan Su <su.zhengyuan@u.nus.edu> * refactor: round 3 — dead modules, helpers, and private cascades state_manager.py and llm_info.py have no importers anywhere — entire modules removed. Within utils/, scheduler/, and io_locations/, more top-level helpers had no callers (iter_batch, execute_unordered, run_coroutine_blocking, detect_sccs, calculate_node_depths, default_worker_filter, filtered_dependencies, ExecutionPlan, GraphValidationError, plus the four io_locations top-level entry points: normalize_location_key, load_input_location, ensure_input_location_exists, ensure_output_location_available). Their removal cascades: the io_locations DB chain (_db_conn, _split_table, _ensure_db_*, _read_db_column) and the S3 single-object chain (_is_s3_folder_prefix, _is_s3_image_object, _ensure_s3_object_*, _read_s3_object, _list_s3_objects) only existed to support those entry points, so they go too — and with them the psycopg / sql / DBLocation imports. The sharded S3 path (write_sharded_index, read_s3_bytes, read_s3_json, list_sharded_index) stays; it has external callers. build_dependency_list in schedule/models.py was only used by the removed filtered_dependencies and follows it out. Left intact (push-back on review): - tests/runtime/server/test_run_batch.py:FakeContext.Queue(maxsize=...). The parameter is intentional API parity — production code calls ctx.Queue(maxsize=1) at runtime/server.py:2400, so the mock has to accept the kwarg even though FakeQueue ignores capacity. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Zhengyuan Su <su.zhengyuan@u.nus.edu> * refactor: drop prefix/radix-tree feature surface and cascading dead helpers The prefix/radix-tree machinery belongs to the remote optimizer, not the OSS runtime. Removing it lets every method, helper, and type that only existed to serve that machinery follow it out. What that pulls along, verified zero non-self callers in src/, tests/, and examples/: - The full Op-side prefix surface: get_input_slice (abstract + every override), signature / _state_signature / _input_signature, replace_input, plus the LLMChatOp _structural_outputs_signature helper it owned. - The Graph/CompiledGraph prefix surface: build_input_slices, build_llm_dependencies, _get_llm_dependencies, the input_slices / data_size properties, plus merge, disjoint_subgraphs, recompile, apply_to_data, visualize, save, load — and the module-level from_ops / from_json / save / load wrappers. - Slice (lumilake.common) and its supporting partition / identity in utils.utils, detect_wccs in utils.graph. - Optimizer leftovers from the same theme: QueryPlanOption, DBQuery.plans, QueryPlanChoice.samples, the _split_bonus_aware_exec_cost helper. - Round-4 follow-ons unrelated to the prefix removal but in the same comprehensive sweep: runtime/data.py (orphan), runtime/utils/pool.py (no importers after the loop-variant trim), MPQueue, the three MP / concurrent EventLoop variants, the cli/core/query.parse_query_filters helper (zero callers). routes/trace.py grows a small fast path: when job storage is an in-memory backend, skip asyncio.to_thread — the threading hop only helps for I/O-backed storages. (Behavior unchanged for real S3-backed deployments; tests run with the in-memory backend now skip the thread hop.) 237 → 235 tests passing (two removed with utils/prefix/). pre-commit clean (isort/black/ruff/codespell/mypy). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Signed-off-by: Zhengyuan Su <su.zhengyuan@u.nus.edu> * ci: add env and package validation workflows Signed-off-by: Zhengyuan Su <su.zhengyuan@u.nus.edu> --------- Signed-off-by: Zhengyuan Su <su.zhengyuan@u.nus.edu> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 0f3cb76 commit ee068bf

61 files changed

Lines changed: 305 additions & 7254 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.template

Lines changed: 0 additions & 43 deletions
This file was deleted.

.github/dependabot.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ updates:
55
schedule:
66
interval: weekly
77
labels: ["ci"]
8+
commit-message:
9+
prefix: "build"
10+
include: "scope"
811
# Wait 7 days after an action is released before bumping. Protects
912
# against actively-malicious releases and 0-days in fresh versions.
1013
cooldown:

.github/workflows/env-examples.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: env-examples Check
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths-ignore:
8+
- '**.md'
9+
- 'docs/**'
10+
pull_request:
11+
paths-ignore:
12+
- '**.md'
13+
- 'docs/**'
14+
15+
permissions:
16+
contents: read
17+
18+
concurrency:
19+
group: ${{ github.workflow }}-${{ github.ref }}
20+
cancel-in-progress: true
21+
22+
jobs:
23+
verify:
24+
name: Verify env example files
25+
runs-on: self-hosted
26+
steps:
27+
- name: Checkout
28+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
29+
with:
30+
persist-credentials: false
31+
32+
- name: Set up uv
33+
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
34+
with:
35+
version: "0.11.8"
36+
37+
- name: Install dependencies
38+
run: uv sync --frozen
39+
40+
- name: Verify env example files
41+
run: uv run scripts/dev/check_env_examples.py
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Package Build
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths-ignore:
8+
- '**.md'
9+
- 'docs/**'
10+
pull_request:
11+
paths-ignore:
12+
- '**.md'
13+
- 'docs/**'
14+
15+
permissions:
16+
contents: read
17+
18+
concurrency:
19+
group: ${{ github.workflow }}-${{ github.ref }}
20+
cancel-in-progress: true
21+
22+
jobs:
23+
package-build:
24+
name: Build and smoke-test package
25+
runs-on: self-hosted
26+
steps:
27+
- name: Checkout
28+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
29+
with:
30+
persist-credentials: false
31+
32+
- name: Set up uv
33+
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
34+
with:
35+
version: "0.11.8"
36+
37+
- name: Install build environment
38+
run: uv sync --all-groups --all-extras --frozen
39+
40+
- name: Build distributions
41+
run: uv build --out-dir dist
42+
43+
- name: Verify distributions
44+
run: uv run scripts/ci/check_package_build.py --dist dist

.gitleaksignore

Lines changed: 0 additions & 1 deletion
This file was deleted.

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Guidance for agentic tools (Claude Code, Cursor, Aider, etc.) working in this re
77
- Environment is managed by `uv`. The system may not have Python installed directly. Always use `uv run ...` to execute commands.
88
- `uv sync --group lint --group test --extra cli` installs everything a development-focused agent needs.
99
- `uv run pre-commit run --all-files` runs every formatting / lint / type-check / spell-check the CI runs. This must pass before any PR lands. The exact tool set lives in `.pre-commit-config.yaml`.
10-
- **Scratch space.** Keep throwaway scripts / experiments under `agent_space/` (gitignored) or alongside existing `.bak` files. Never commit scratch.
10+
- **Scratch.** Never commit throwaway scripts / experiments.
1111

1212
## Design Discipline
1313

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ The Docker image installs from `pyproject.toml` directly via `pip install .` on
8686
uv sync --group test --group lint
8787

8888
# Environment for a local run — can be exported or placed in .env
89-
cp .env.template .env
89+
cp .env.example .env
9090
$EDITOR .env
9191

9292
uv run python -m lumilake.server.main

pyproject.toml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ dependencies = [
1212
server = [
1313
"fastapi[standard]>=0.115.6",
1414
"openai>=1.58.1",
15-
"backoff>=2.2.1",
1615
"requests>=2.32.3",
1716
"urllib3>=2.7.0",
1817
"aiohttp>=3.11.11",
@@ -21,13 +20,10 @@ server = [
2120
"minio>=7.2.8",
2221
"networkx[default]>=3.4.2",
2322
"matplotlib>=3.10.1",
24-
"cachetools>=6.2.0",
2523
"dill>=0.4.0",
2624
"psycopg[binary]>=3.2.0",
2725
"psycopg-pool>=3.2.0",
28-
"sqlglot>=26.30.0",
2926
"rich>=13.6.0",
30-
"tabulate>=0.9.0",
3127
"lumid-hooks==0.1.0",
3228
"flowmesh-sdk==0.1.0",
3329
"lumid-data-sdk==0.1.0",
@@ -59,7 +55,6 @@ lint = [
5955
"codespell==2.4.2",
6056
"isort==8.0.1",
6157
"types-requests==2.33.0.20260503",
62-
"types-cachetools==7.0.0.20260503",
6358
"types-pyyaml==6.0.12.20260408",
6459
"types-docker==7.1.0.20260409",
6560
"pre-commit==4.6.0",
@@ -91,7 +86,7 @@ skip = [".venv"]
9186

9287
[tool.ruff]
9388
target-version = "py312"
94-
exclude = [".venv", "agent_space"]
89+
exclude = [".venv"]
9590

9691
[tool.ruff.lint]
9792
select = ["E", "F", "UP", "I"]

scripts/ci/check_package_build.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"""Validate built Lumilake distributions."""
2+
3+
import argparse
4+
import subprocess
5+
import tempfile
6+
import venv
7+
from pathlib import Path
8+
from zipfile import ZipFile
9+
10+
REQUIRED_TOP_LEVELS = {"lumilake", "lumilake_hook"}
11+
12+
13+
def _script_bin(env_dir: Path, name: str) -> Path:
14+
return env_dir / "bin" / name
15+
16+
17+
def _run(cmd: list[str]) -> None:
18+
subprocess.run(cmd, check=True) # nosec B603: fixed argv list, no shell.
19+
20+
21+
def _single_file(dist_dir: Path, pattern: str) -> Path:
22+
matches = sorted(dist_dir.glob(pattern))
23+
if len(matches) != 1:
24+
raise SystemExit(f"Expected one {pattern!r}, found {len(matches)}")
25+
return matches[0]
26+
27+
28+
def _check_wheel(wheel: Path) -> None:
29+
with ZipFile(wheel) as zf:
30+
names = set(zf.namelist())
31+
top_levels = {name.split("/", 1)[0] for name in names if "/" in name}
32+
missing = sorted(REQUIRED_TOP_LEVELS - top_levels)
33+
if missing:
34+
raise SystemExit("wheel missing top-level packages: " + ", ".join(missing))
35+
if "lumilake/py.typed" not in names:
36+
raise SystemExit("wheel missing lumilake/py.typed")
37+
entry_points = [
38+
name for name in names if name.endswith(".dist-info/entry_points.txt")
39+
]
40+
if len(entry_points) != 1:
41+
raise SystemExit("wheel missing entry_points.txt")
42+
if any(name.startswith("tests/") for name in names):
43+
raise SystemExit("wheel should not contain tests/")
44+
45+
46+
def _smoke_import(wheel: Path) -> None:
47+
with tempfile.TemporaryDirectory(prefix="lumilake-package-smoke-") as tmp:
48+
env_dir = Path(tmp) / ".venv"
49+
venv.EnvBuilder(with_pip=True).create(env_dir)
50+
python = _script_bin(env_dir, "python")
51+
_run([python.as_posix(), "-m", "pip", "install", "--no-deps", wheel.as_posix()])
52+
_run([python.as_posix(), "-c", "import lumilake; assert lumilake.__version__"])
53+
54+
55+
def main() -> int:
56+
parser = argparse.ArgumentParser(description=__doc__)
57+
parser.add_argument(
58+
"--dist",
59+
default="dist",
60+
type=Path,
61+
help="Directory containing distributions built by `uv build`.",
62+
)
63+
args = parser.parse_args()
64+
65+
dist_dir = args.dist.resolve()
66+
if not dist_dir.is_dir():
67+
raise SystemExit(f"Distribution directory does not exist: {dist_dir}")
68+
69+
wheel = _single_file(dist_dir, "lumilake-*-py3-none-any.whl")
70+
_single_file(dist_dir, "lumilake-*.tar.gz")
71+
_check_wheel(wheel)
72+
_smoke_import(wheel)
73+
return 0
74+
75+
76+
if __name__ == "__main__":
77+
raise SystemExit(main())

scripts/dev/check_env_examples.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""Verify committed Lumilake env examples match the deploy schema."""
2+
3+
import argparse
4+
import re
5+
from pathlib import Path
6+
7+
from lumilake.deploy import doctor
8+
9+
REPO_ROOT = Path(__file__).resolve().parents[2]
10+
ENV_EXAMPLE = REPO_ROOT / ".env.example"
11+
12+
_ASSIGNMENT_RE = re.compile(r"^\s*#?\s*([A-Z][A-Z0-9_]*)\s*=")
13+
_FORBIDDEN_KEYS = frozenset(
14+
{
15+
"LUMILAKE_STRATEGY_AUTOLOAD_MODULES",
16+
"DEPLOY_PROFILE",
17+
"CREDENTIALS_JSON",
18+
}
19+
)
20+
21+
22+
def _example_keys(path: Path) -> set[str]:
23+
keys: set[str] = set()
24+
for line in path.read_text().splitlines():
25+
match = _ASSIGNMENT_RE.match(line)
26+
if match:
27+
keys.add(match.group(1))
28+
return keys
29+
30+
31+
def main() -> int:
32+
parser = argparse.ArgumentParser(description=__doc__)
33+
parser.parse_args()
34+
35+
if not ENV_EXAMPLE.is_file():
36+
raise SystemExit(f"Missing env example: {ENV_EXAMPLE.relative_to(REPO_ROOT)}")
37+
38+
keys = _example_keys(ENV_EXAMPLE)
39+
required = set(doctor._ALWAYS_REQUIRED + doctor._DIRECT_MODE_REQUIRED)
40+
missing = sorted(required - keys)
41+
unknown = sorted(keys - doctor._KNOWN_KEYS)
42+
forbidden = sorted(keys & _FORBIDDEN_KEYS)
43+
44+
failed = False
45+
if missing:
46+
failed = True
47+
print("Missing required env example keys:")
48+
for key in missing:
49+
print(f"- {key}")
50+
if unknown:
51+
failed = True
52+
print("Unknown env example keys:")
53+
for key in unknown:
54+
print(f"- {key}")
55+
if forbidden:
56+
failed = True
57+
print("Forbidden legacy env example keys:")
58+
for key in forbidden:
59+
print(f"- {key}")
60+
61+
return 1 if failed else 0
62+
63+
64+
if __name__ == "__main__":
65+
raise SystemExit(main())

0 commit comments

Comments
 (0)