Spaces:
Sleeping
Sleeping
| """`pred_label=None` server crash repro for the Lexsi platform team. | |
| Reproduces the bug documented in `docs/sdk_issues.md` Β§2: | |
| `ProjectConfig.pred_label` is typed `Optional[str]` in the SDK, but the | |
| server-side training pipeline does direct subscript access on the key | |
| and crashes on `None`. Activity Log surfaces a bare `'pred_label'` line | |
| followed by `#05-013` (XAI step) or `#05-001` (model build step) | |
| depending on which handler runs first. | |
| Failure mode: | |
| Activity Log β Started building TabICL_v1 model | |
| Building Model | |
| 'pred_label' | |
| Failed while building model. #05-001 | |
| Client-side β Exception("") (empty message) from `upload_data` | |
| Workaround (what the agent does): | |
| Set `pred_label="Prediction"` unconditionally in the ProjectConfig. | |
| Dataset: `data/context_df.csv` β same 682-row PKDD binary | |
| classification training set used by the TabICL repro. | |
| How to run: | |
| export SDK_ACCESS_TOKEN=<your token> | |
| export LEXSI_ORG_NAME=<org, default "personal"> | |
| export LEXSI_WORKSPACE_NAME=<workspace> | |
| uv run python scripts/repro_tabicl/repro_pred_label_none.py | |
| """ | |
| from __future__ import annotations | |
| import os | |
| import sys | |
| import time | |
| from datetime import datetime | |
| from pathlib import Path | |
| import pandas as pd | |
| HERE = Path(__file__).resolve().parent | |
| CONTEXT_CSV = HERE / "data" / "context_df.csv" | |
| def _require_env() -> tuple[str, str, str]: | |
| token = os.environ.get("SDK_ACCESS_TOKEN") | |
| org = os.environ.get("LEXSI_ORG_NAME", "personal") | |
| ws = os.environ.get("LEXSI_WORKSPACE_NAME") | |
| if not token or not ws: | |
| print( | |
| "error: set SDK_ACCESS_TOKEN and LEXSI_WORKSPACE_NAME (and " | |
| "LEXSI_ORG_NAME if not 'personal').", | |
| file=sys.stderr, | |
| ) | |
| sys.exit(2) | |
| return token, org, ws | |
| def main() -> None: | |
| token, org_name, ws_name = _require_env() | |
| from lexsi_sdk import xai as lexsi # type: ignore[import-not-found] | |
| print(f"# Lexsi pred_label=None repro β {datetime.now().isoformat(timespec='seconds')}") | |
| print(f"# org={org_name!r} workspace={ws_name!r}") | |
| lexsi.login(sdk_access_token=token) | |
| org = lexsi.organization(org_name) | |
| ws = org.workspace(ws_name) | |
| proj_name = f"repronone{int(time.time()) % 1_000_000}" | |
| print(f"\n# creating fresh tabular project: {proj_name}") | |
| project = None | |
| last_err: Exception | None = None | |
| for attempt in range(1, 4): | |
| try: | |
| project = ws.create_project( | |
| project_name=proj_name, | |
| modality="tabular", | |
| project_type="classification", | |
| ) | |
| break | |
| except Exception as e: | |
| last_err = e | |
| print(f" create_project attempt {attempt}/3 failed: {e}") | |
| time.sleep(2) | |
| if project is None: | |
| raise RuntimeError(f"create_project failed after 3 attempts: {last_err}") | |
| print(f"# project ready: {proj_name}") | |
| context_df = pd.read_csv(CONTEXT_CSV) | |
| train_tag = "reprotrain" | |
| print(f"\n# training: {context_df.shape} target=y_default tag={train_tag!r}") | |
| config = { | |
| "unique_identifier": "loan_id", | |
| "true_label": "y_default", | |
| "tag": train_tag, | |
| "model_name": "TabICL", | |
| "pred_label": None, | |
| "feature_exclude": [], | |
| "feature_encodings": {}, | |
| "drop_duplicate_uid": True, | |
| "handle_errors": True, | |
| "handle_data_imbalance": False, | |
| "sample_percentage": None, | |
| "xai_method": [], | |
| } | |
| print("\n# uploading training data with pred_label=None β expect server " | |
| "crash visible in Activity Log as `'pred_label'` + #05-001 or #05-013") | |
| try: | |
| project.upload_data( | |
| data=context_df, | |
| tag=train_tag, | |
| config=config, | |
| compute_type="T4.small", | |
| ) | |
| print("# (unexpected) upload_data returned without raising β " | |
| "check Activity Log; the model build may still fail asynchronously.") | |
| except Exception as e: | |
| print(f"# upload_data raised: {type(e).__name__}: {e!r}") | |
| print(f"\n# done. project left behind for inspection: {proj_name}") | |
| print("# delete with: project.delete_project()") | |
| if __name__ == "__main__": | |
| main() |