lyceum-cli 1.0.31__py3-none-any.whl → 1.0.33__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -59,6 +59,22 @@ GPU_VRAM_GB = {
59
59
  "gpu.rtx6000pro": 48,
60
60
  }
61
61
 
62
+ # Fallback pricing per hour (used when API doesn't return prices)
63
+ GPU_PRICE_PER_HOUR = {
64
+ "cpu": 0.20,
65
+ "gpu": 0.39,
66
+ "gpu.t4": 0.39,
67
+ "gpu.t4.64gb": 1.50,
68
+ "gpu.a100": 2.00,
69
+ "gpu.a100.40gb": 1.95,
70
+ "gpu.a100.80gb": 1.99,
71
+ "gpu.h100": 3.29,
72
+ "gpu.h200": 3.69,
73
+ "gpu.l40s": 1.49,
74
+ "gpu.b200": 5.69,
75
+ "gpu.rtx6000pro": 1.95,
76
+ }
77
+
62
78
 
63
79
  def format_gpu_name(profile: str) -> str:
64
80
  """Format GPU profile name for display."""
@@ -95,6 +111,9 @@ def fetch_gpu_pricing() -> dict[str, float]:
95
111
  def calculate_cost(execution_time_s: float, hardware_profile: str, pricing: dict[str, float]) -> float | None:
96
112
  """Calculate cost based on execution time and GPU pricing."""
97
113
  price_per_hour = pricing.get(hardware_profile)
114
+ # Fallback to hardcoded pricing if API doesn't have this profile
115
+ if price_per_hour is None or price_per_hour == 0:
116
+ price_per_hour = GPU_PRICE_PER_HOUR.get(hardware_profile)
98
117
  if price_per_hour is None or price_per_hour == 0:
99
118
  return None
100
119
  return execution_time_s * (price_per_hour / 3600)
@@ -670,14 +689,6 @@ def predict_memory(
670
689
  imports: list[str] | None = typer.Option(
671
690
  None, "--import", help="Pre-import modules (can be used multiple times)"
672
691
  ),
673
- mixed_precision: str | None = typer.Option(
674
- None, "--mixed-precision", "-mp",
675
- help="Mixed precision dtype (fp16, bf16)"
676
- ),
677
- strategy: str | None = typer.Option(
678
- None, "--strategy", "-s",
679
- help="Parallelization strategy (ddp, fsdp, zero1, zero2, zero3)"
680
- ),
681
692
  use_config: bool = typer.Option(
682
693
  True, "--use-config/--no-config",
683
694
  help="Use workspace config from .lyceum/config.json if available"
@@ -689,9 +700,7 @@ def predict_memory(
689
700
  full GPU profiling. Faster than 'predict run'.
690
701
 
691
702
  Examples:
692
- lyceum predict memory train.py
693
- lyceum predict memory train.py --mixed-precision fp16
694
- lyceum predict memory train.py --strategy fsdp
703
+ lyceum gpu-selection memory train.py
695
704
  """
696
705
  status = StatusLine()
697
706
 
@@ -730,12 +739,6 @@ def predict_memory(
730
739
  if import_files:
731
740
  payload["import_files"] = import_files
732
741
 
733
- # TODO: When backend supports it, add mixed_precision and strategy to payload
734
- if mixed_precision:
735
- console.print(f"[dim]Note: --mixed-precision {mixed_precision} (backend support coming soon)[/dim]")
736
- if strategy:
737
- console.print(f"[dim]Note: --strategy {strategy} (backend support coming soon)[/dim]")
738
-
739
742
  execution_id = submit_gpu_selection(payload, status)
740
743
  console.print(f"[dim]Execution ID: {execution_id}[/dim]")
741
744
 
@@ -73,15 +73,22 @@ def load_workspace_config(file_path: Path | None = None) -> dict | None:
73
73
 
74
74
  def read_code_from_source(code_or_file: str, status: StatusLine = None) -> tuple[str, Path | None, str | None]:
75
75
  """Read code from file or return as-is if it's inline code."""
76
- file_path = Path(code_or_file) if Path(code_or_file).exists() else None
76
+ # Check if input looks like a file path
77
+ looks_like_file = code_or_file.endswith((".py", ".ipynb")) or "/" in code_or_file or "\\" in code_or_file
77
78
 
78
- if file_path:
79
+ file_path = Path(code_or_file)
80
+ if file_path.exists():
79
81
  if status:
80
82
  status.update(f"Reading {file_path.name}...")
81
83
  with open(file_path) as f:
82
84
  code_content = f.read()
83
85
  return code_content, file_path, file_path.name
84
86
 
87
+ # If it looks like a file but doesn't exist, raise an error
88
+ if looks_like_file:
89
+ raise FileNotFoundError(f"File not found: {code_or_file}")
90
+
91
+ # Otherwise treat as inline code
85
92
  return code_or_file, None, None
86
93
 
87
94
 
lyceum/shared/config.py CHANGED
@@ -129,7 +129,7 @@ class _Config:
129
129
  if self.is_token_expired():
130
130
  console.print("[dim]Token expired, attempting refresh...[/dim]")
131
131
  if not self.refresh_access_token():
132
- console.print("[red]Token refresh failed. Please run 'lyceum login' again.[/red]")
132
+ console.print("[red]Token refresh failed. Please run 'lyceum auth login' again.[/red]")
133
133
  raise typer.Exit(1)
134
134
 
135
135
  # Return config instance - commands use httpx directly
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lyceum-cli
3
- Version: 1.0.31
3
+ Version: 1.0.33
4
4
  Summary: Command-line interface for Lyceum Cloud Execution API
5
5
  Home-page: https://lyceum.technology
6
6
  Author: Lyceum Team
@@ -8,9 +8,9 @@ lyceum/external/compute/execution/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZ
8
8
  lyceum/external/compute/execution/config.py,sha256=6JJgLJnDPTwevEaNdB1nEICih_qbBmws5u5_S9gj7k0,8866
9
9
  lyceum/external/compute/execution/docker.py,sha256=0Y6lxJAm56Jrl0HxeNz1mX6DGs556i2iMN9_U1JQP0c,9635
10
10
  lyceum/external/compute/execution/docker_compose.py,sha256=YsWPnw5nB1ZpqjU9X8o_klT78I5m46PapVwVEeWra_8,9189
11
- lyceum/external/compute/execution/gpu_selection.py,sha256=B6x8enjdH07eUR4s1eobxGmekLyJ8-IbadxFjOAjApw,39109
11
+ lyceum/external/compute/execution/gpu_selection.py,sha256=LX3Ar4srw6s8PcKxASnzVOrLH6tmU1vl7rHSAkrsoEE,38900
12
12
  lyceum/external/compute/execution/notebook.py,sha256=Gw9UhJ-UjYhpjdIYQ4IMYhVjhSkAFpOQ9aFYj1qOeww,7542
13
- lyceum/external/compute/execution/python.py,sha256=8Y9ElWs9RdauQbhECKcBPSoT0XZeGhXZ_pkEpr3sGro,12878
13
+ lyceum/external/compute/execution/python.py,sha256=-7GVRpQlQwn5Je_7B-LZAagEZ5mE5V4Ijs2wRThd43Q,13193
14
14
  lyceum/external/compute/execution/workloads.py,sha256=4fsRWbYGmsQMGPPIN1jUG8cG5NPG9yV26ANJ-DtaXqc,5844
15
15
  lyceum/external/compute/inference/__init__.py,sha256=4YLoUKDEzitexynJv_Q5O0w1lty8CJ6uyRxuc1LiaBw,89
16
16
  lyceum/external/compute/inference/batch.py,sha256=F4MlR2IEi1X7qUo3UDUVRWclHLLmmjqu7KZ3RkHIjNM,4349
@@ -22,15 +22,15 @@ lyceum/external/vms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
22
22
  lyceum/external/vms/instances.py,sha256=8DKpI8PbyZFzk5RT-IPgoMDjkf_-HC-2pJKuSFs-5BA,11007
23
23
  lyceum/external/vms/management.py,sha256=dYEkN5Qiur-SG4G5CLOk2Rbr0HW3rK1BROSp0K6KxC8,15405
24
24
  lyceum/shared/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
25
- lyceum/shared/config.py,sha256=gEXf_hEmgUq3rSxU2SY75qg32mFS6qsruox7uvQlf3I,5334
25
+ lyceum/shared/config.py,sha256=vgmspvId3D60ESJs2LLhZ5WUglIaJ7kaehNnWB7HEuA,5339
26
26
  lyceum/shared/display.py,sha256=-VSAfoa0yivTvxRrN2RYr2Sq1x_msZqENjnkSedmbhQ,4444
27
27
  lyceum/shared/imports.py,sha256=wEG4wfVTIqJ6MBWDRAN96iGmVCb9ST2aOqSjkbvajug,11768
28
28
  lyceum/shared/streaming.py,sha256=wFb7w7fra63y8WWaIA8_E1Z6Sx_6G-0J53Zh010eZgk,9355
29
29
  lyceum_cloud_execution_api_client/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
30
30
  lyceum_cloud_execution_api_client/api/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
31
31
  lyceum_cloud_execution_api_client/models/__init__.py,sha256=AMlb9R9O9aNC9hvKz_8TFpEfOolYC3VtFS5JX17kYks,4888
32
- lyceum_cli-1.0.31.dist-info/METADATA,sha256=bGp9mqLakov3SeduGI7Fo_V5jdsHyEzh5UsisZgBhK8,1482
33
- lyceum_cli-1.0.31.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
34
- lyceum_cli-1.0.31.dist-info/entry_points.txt,sha256=Oq-9wDkxVd6MHgNiUTYwXI9SGhvR3VkD7Mvk0xhiUZo,43
35
- lyceum_cli-1.0.31.dist-info/top_level.txt,sha256=CR7FEMloAXgLsHUR6ti3mWNcpgje27HRHSfq8doIils,41
36
- lyceum_cli-1.0.31.dist-info/RECORD,,
32
+ lyceum_cli-1.0.33.dist-info/METADATA,sha256=N3bGDPySJO1veoawv0LpK7mMETe1cWr6mHPruUcha-8,1482
33
+ lyceum_cli-1.0.33.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
34
+ lyceum_cli-1.0.33.dist-info/entry_points.txt,sha256=Oq-9wDkxVd6MHgNiUTYwXI9SGhvR3VkD7Mvk0xhiUZo,43
35
+ lyceum_cli-1.0.33.dist-info/top_level.txt,sha256=CR7FEMloAXgLsHUR6ti3mWNcpgje27HRHSfq8doIils,41
36
+ lyceum_cli-1.0.33.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.10.2)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5