lyceum-cli 1.0.14__py3-none-any.whl → 1.0.18__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.
@@ -0,0 +1,134 @@
1
+ """
2
+ Streaming utilities for execution output
3
+ """
4
+
5
+ import json
6
+ import re
7
+ import httpx
8
+ from rich.console import Console
9
+
10
+ from .config import config
11
+
12
+ console = Console()
13
+
14
+
15
+ def strip_ansi_codes(text: str) -> str:
16
+ """Remove ANSI escape codes from text"""
17
+ ansi_escape = re.compile(r'\x1b\[[0-9;]*m')
18
+ return ansi_escape.sub('', text)
19
+
20
+
21
+ def stream_execution_output(execution_id: str, streaming_url: str = None) -> bool:
22
+ """Stream execution output in real-time. Returns True if successful, False if failed."""
23
+ if not streaming_url:
24
+ # Fallback to old endpoint if no streaming URL provided
25
+ stream_url = f"{config.base_url}/api/v2/external/execution/streaming/{execution_id}"
26
+ else:
27
+ stream_url = streaming_url
28
+
29
+ try:
30
+ console.print(f"[dim]🔗 Connecting to execution stream...[/dim]")
31
+ console.print(f"[dim]Stream URL: {stream_url}[/dim]")
32
+
33
+ with httpx.stream("GET", stream_url, headers={"Authorization": f"Bearer {config.api_key}"}, timeout=600.0) as response:
34
+ if response.status_code != 200:
35
+ console.print(f"[red]❌ Stream failed: HTTP {response.status_code}[/red]")
36
+ return False
37
+
38
+ console.print("[dim]📡 Streaming output...[/dim]")
39
+
40
+ for line in response.iter_lines():
41
+ if line.strip():
42
+ # Parse Server-Sent Events format
43
+ if line.startswith("data: "):
44
+ data_json = line[6:] # Remove "data: " prefix
45
+ try:
46
+ data = json.loads(data_json)
47
+ event_type = data.get("type", "unknown")
48
+
49
+ if event_type == "output":
50
+ # Print output without extra formatting, stripping ANSI codes
51
+ output = data.get("content", "") # Fixed: server sends "content" not "output"
52
+ if output:
53
+ clean_output = strip_ansi_codes(output)
54
+ console.print(clean_output, end="")
55
+
56
+ elif event_type == "completed":
57
+ status = data.get("status", "unknown")
58
+ exec_time = data.get("execution_time", 0)
59
+
60
+ if status == "completed":
61
+ console.print(f"\n[green]✅ Execution completed successfully in {exec_time:.1f}s[/green]")
62
+ elif status in ["failed_user", "failed_system"]:
63
+ console.print(f"\n[red]❌ Execution failed: {status}[/red]")
64
+ # Show errors if available
65
+ errors = data.get("errors")
66
+ if errors:
67
+ console.print(f"[red]Error: {errors}[/red]")
68
+ elif status == "timeout":
69
+ console.print(f"\n[yellow]⏰ Execution timed out after {exec_time:.1f}s[/yellow]")
70
+ elif status == "cancelled":
71
+ console.print(f"\n[yellow]🛑 Execution was cancelled[/yellow]")
72
+
73
+ return status == "completed"
74
+
75
+ elif event_type == "error":
76
+ error_msg = data.get("message", "Unknown error")
77
+ console.print(f"\n[red]❌ Error: {error_msg}[/red]")
78
+ return False
79
+
80
+ except json.JSONDecodeError:
81
+ # Skip malformed JSON
82
+ continue
83
+
84
+ console.print(f"\n[yellow]⚠️ Stream ended without completion signal[/yellow]")
85
+ # Fallback: poll execution status
86
+ return check_execution_status(execution_id)
87
+
88
+ except Exception as e:
89
+ console.print(f"\n[red]❌ Streaming error: {e}[/red]")
90
+ # Fallback: poll execution status
91
+ return check_execution_status(execution_id)
92
+
93
+
94
+ def check_execution_status(execution_id: str) -> bool:
95
+ """Check execution status as fallback when streaming fails."""
96
+ import time
97
+
98
+ console.print("[dim]⏳ Checking execution status...[/dim]")
99
+
100
+ for _ in range(30): # Poll for up to 30 seconds
101
+ try:
102
+ response = httpx.get(
103
+ f"{config.base_url}/api/v2/external/execution/streaming/{execution_id}/status",
104
+ headers={"Authorization": f"Bearer {config.api_key}"},
105
+ timeout=10.0
106
+ )
107
+
108
+ if response.status_code == 200:
109
+ data = response.json()
110
+ status = data.get('status', 'unknown')
111
+
112
+ if status == 'completed':
113
+ console.print(f"[green]✅ Execution completed successfully![/green]")
114
+ return True
115
+ elif status in ['failed_user', 'failed_system', 'failed']:
116
+ console.print(f"[red]❌ Execution failed: {status}[/red]")
117
+ errors = data.get('errors')
118
+ if errors:
119
+ console.print(f"[red]Error: {errors}[/red]")
120
+ return False
121
+ elif status in ['timeout', 'cancelled']:
122
+ console.print(f"[yellow]⚠️ Execution {status}[/yellow]")
123
+ return False
124
+ elif status in ['running', 'pending', 'queued']:
125
+ # Still running, continue polling
126
+ time.sleep(1)
127
+ continue
128
+
129
+ except Exception as e:
130
+ console.print(f"[red]Error checking status: {e}[/red]")
131
+ break
132
+
133
+ console.print("[yellow]⚠️ Status check timed out[/yellow]")
134
+ return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lyceum-cli
3
- Version: 1.0.14
3
+ Version: 1.0.18
4
4
  Summary: Command-line interface for Lyceum Cloud Execution API
5
5
  Home-page: https://lyceum.technology
6
6
  Author: Lyceum Team
@@ -0,0 +1,25 @@
1
+ lyceum/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ lyceum/main.py,sha256=GO__4_w7Xrr2M6sUlgtG5VK6q64Ako-Qm1i5tcuYk2U,934
3
+ lyceum/external/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ lyceum/external/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ lyceum/external/auth/login.py,sha256=GYhvhQrWG49LYsqxfNdVfs59GQtjKOlRmcytww9PCWk,23289
6
+ lyceum/external/compute/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ lyceum/external/compute/execution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ lyceum/external/compute/execution/python.py,sha256=IiQpudxLAD4lMaQsvON6MGPNGYtEW9Zoip9dSv8KI0g,3745
9
+ lyceum/external/compute/inference/__init__.py,sha256=4YLoUKDEzitexynJv_Q5O0w1lty8CJ6uyRxuc1LiaBw,89
10
+ lyceum/external/compute/inference/batch.py,sha256=OHwJndqvsQx0K0-3to8Tc9HB2xA6iq1MNvXvpMxi5Oc,11775
11
+ lyceum/external/compute/inference/chat.py,sha256=IZri9YrgMWHHQkJMj_ausdjBgNmqBAluAZcmRwJ-sIM,8756
12
+ lyceum/external/compute/inference/models.py,sha256=VVHMUhTPVhLKiuvC9Q1zvBD-lM4KDJPUqTmFO7kHpUA,10319
13
+ lyceum/external/general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ lyceum/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ lyceum/shared/config.py,sha256=7HAKztOvEv8zrn_2t-9iZlrgkV2n_5sIN-XOK7Mb8pI,5550
16
+ lyceum/shared/display.py,sha256=LeGZjCFn8_8sOgao2pni_qN3OhiFwKJHpEJLjCwftwM,4884
17
+ lyceum/shared/streaming.py,sha256=-_MLgrACwe1oU5n3UG4kzg9TcUQXc3cLNV6WyplEc_k,6073
18
+ lyceum_cloud_execution_api_client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ lyceum_cloud_execution_api_client/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ lyceum_cloud_execution_api_client/models/__init__.py,sha256=AMlb9R9O9aNC9hvKz_8TFpEfOolYC3VtFS5JX17kYks,4888
21
+ lyceum_cli-1.0.18.dist-info/METADATA,sha256=Xr3_q1LQTamNgwcEidQ6QHCdnQcdxK-AY-wyVTwp2f4,1482
22
+ lyceum_cli-1.0.18.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
+ lyceum_cli-1.0.18.dist-info/entry_points.txt,sha256=Oq-9wDkxVd6MHgNiUTYwXI9SGhvR3VkD7Mvk0xhiUZo,43
24
+ lyceum_cli-1.0.18.dist-info/top_level.txt,sha256=CR7FEMloAXgLsHUR6ti3mWNcpgje27HRHSfq8doIils,41
25
+ lyceum_cli-1.0.18.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ lyceum
2
+ lyceum_cloud_execution_api_client
File without changes
File without changes
@@ -0,0 +1,105 @@
1
+ """Contains all the data models used in inputs/outputs"""
2
+
3
+ from .abort_response import AbortResponse
4
+ from .api_key_create import ApiKeyCreate
5
+ from .api_key_create_response import ApiKeyCreateResponse
6
+ from .api_key_response import ApiKeyResponse
7
+ from .body_upload_bulk_files_api_v2_external_storage_upload_bulk_post import (
8
+ BodyUploadBulkFilesApiV2ExternalStorageUploadBulkPost,
9
+ )
10
+ from .body_upload_file_api_v1_upload_file_post import BodyUploadFileApiV1UploadFilePost
11
+ from .body_upload_file_api_v2_external_storage_upload_post import BodyUploadFileApiV2ExternalStorageUploadPost
12
+ from .bulk_upload_response import BulkUploadResponse
13
+ from .bulk_upload_result import BulkUploadResult
14
+ from .checkout_session_request import CheckoutSessionRequest
15
+ from .checkout_session_response import CheckoutSessionResponse
16
+ from .cloud_storage_status import CloudStorageStatus
17
+ from .cloud_storage_status_aws_s3 import CloudStorageStatusAwsS3
18
+ from .cloud_storage_status_azure_blob import CloudStorageStatusAzureBlob
19
+ from .cloud_storage_status_gcp_storage import CloudStorageStatusGcpStorage
20
+ from .code_execution import CodeExecution
21
+ from .connect_request import ConnectRequest
22
+ from .connect_request_credentials import ConnectRequestCredentials
23
+ from .create_checkout_session_request import CreateCheckoutSessionRequest
24
+ from .credits_balance import CreditsBalance
25
+ from .delete_user_request import DeleteUserRequest
26
+ from .docker_execution import DockerExecution
27
+ from .docker_execution_docker_env_type_0 import DockerExecutionDockerEnvType0
28
+ from .docker_execution_response import DockerExecutionResponse
29
+ from .execution_response import ExecutionResponse
30
+ from .execution_response_result_files_type_0 import ExecutionResponseResultFilesType0
31
+ from .execution_response_result_files_type_0_additional_property import (
32
+ ExecutionResponseResultFilesType0AdditionalProperty,
33
+ )
34
+ from .execution_summary import ExecutionSummary
35
+ from .file_info import FileInfo
36
+ from .http_validation_error import HTTPValidationError
37
+ from .login_request import LoginRequest
38
+ from .login_response import LoginResponse
39
+ from .machine_type import MachineType
40
+ from .machine_types_response import MachineTypesResponse
41
+ from .start_execution_api_v1_execution_start_post_response_start_execution_api_v1_execution_start_post import (
42
+ StartExecutionApiV1ExecutionStartPostResponseStartExecutionApiV1ExecutionStartPost,
43
+ )
44
+ from .start_execution_api_v2_external_compute_execution_run_post_response_start_execution_api_v2_external_compute_execution_run_post import (
45
+ StartExecutionApiV2ExternalComputeExecutionRunPostResponseStartExecutionApiV2ExternalComputeExecutionRunPost,
46
+ )
47
+ from .start_prebuilt_execution_aws_credentials import StartPrebuiltExecutionAWSCredentials
48
+ from .start_prebuilt_execution_request import StartPrebuiltExecutionRequest
49
+ from .start_prebuilt_execution_request_docker_run_env_type_0 import StartPrebuiltExecutionRequestDockerRunEnvType0
50
+ from .start_prebuilt_execution_response import StartPrebuiltExecutionResponse
51
+ from .storage_credentials import StorageCredentials
52
+ # from .test_credentials_request import TestCredentialsRequest
53
+ # from .test_credentials_request_credentials import TestCredentialsRequestCredentials
54
+ from .upload_response import UploadResponse
55
+ from .user_credits import UserCredits
56
+ from .validation_error import ValidationError
57
+
58
+ __all__ = (
59
+ "AbortResponse",
60
+ "ApiKeyCreate",
61
+ "ApiKeyCreateResponse",
62
+ "ApiKeyResponse",
63
+ "BodyUploadBulkFilesApiV2ExternalStorageUploadBulkPost",
64
+ "BodyUploadFileApiV1UploadFilePost",
65
+ "BodyUploadFileApiV2ExternalStorageUploadPost",
66
+ "BulkUploadResponse",
67
+ "BulkUploadResult",
68
+ "CheckoutSessionRequest",
69
+ "CheckoutSessionResponse",
70
+ "CloudStorageStatus",
71
+ "CloudStorageStatusAwsS3",
72
+ "CloudStorageStatusAzureBlob",
73
+ "CloudStorageStatusGcpStorage",
74
+ "CodeExecution",
75
+ "ConnectRequest",
76
+ "ConnectRequestCredentials",
77
+ "CreateCheckoutSessionRequest",
78
+ "CreditsBalance",
79
+ "DeleteUserRequest",
80
+ "DockerExecution",
81
+ "DockerExecutionDockerEnvType0",
82
+ "DockerExecutionResponse",
83
+ "ExecutionResponse",
84
+ "ExecutionResponseResultFilesType0",
85
+ "ExecutionResponseResultFilesType0AdditionalProperty",
86
+ "ExecutionSummary",
87
+ "FileInfo",
88
+ "HTTPValidationError",
89
+ "LoginRequest",
90
+ "LoginResponse",
91
+ "MachineType",
92
+ "MachineTypesResponse",
93
+ "StartExecutionApiV1ExecutionStartPostResponseStartExecutionApiV1ExecutionStartPost",
94
+ "StartExecutionApiV2ExternalComputeExecutionRunPostResponseStartExecutionApiV2ExternalComputeExecutionRunPost",
95
+ "StartPrebuiltExecutionAWSCredentials",
96
+ "StartPrebuiltExecutionRequest",
97
+ "StartPrebuiltExecutionRequestDockerRunEnvType0",
98
+ "StartPrebuiltExecutionResponse",
99
+ "StorageCredentials",
100
+ # "TestCredentialsRequest",
101
+ # "TestCredentialsRequestCredentials",
102
+ "UploadResponse",
103
+ "UserCredits",
104
+ "ValidationError",
105
+ )
@@ -1,5 +0,0 @@
1
- lyceum_cli-1.0.14.dist-info/METADATA,sha256=GPKsz9WxGtuFqsRrY92c5dKWDhAvYFdzcBPE-5ew1w8,1482
2
- lyceum_cli-1.0.14.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
3
- lyceum_cli-1.0.14.dist-info/entry_points.txt,sha256=Oq-9wDkxVd6MHgNiUTYwXI9SGhvR3VkD7Mvk0xhiUZo,43
4
- lyceum_cli-1.0.14.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
5
- lyceum_cli-1.0.14.dist-info/RECORD,,
@@ -1 +0,0 @@
1
-