alphai 0.1.1__py3-none-any.whl → 0.2.0__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,473 @@
1
+ """Terminal rendering for Jupyter notebooks using Rich."""
2
+
3
+ from typing import Any, Dict, List, Optional
4
+ from datetime import datetime
5
+
6
+ from rich.console import Console
7
+ from rich.table import Table
8
+ from rich.panel import Panel
9
+ from rich.text import Text
10
+ from rich.syntax import Syntax
11
+ from rich.markdown import Markdown
12
+ from rich.columns import Columns
13
+ from rich.rule import Rule
14
+
15
+
16
+ def format_relative_time(timestamp: str) -> str:
17
+ """Format a timestamp as relative time (e.g., '2 hours ago')."""
18
+ try:
19
+ dt = datetime.fromisoformat(timestamp.replace('Z', '+00:00'))
20
+ now = datetime.now(dt.tzinfo)
21
+ diff = now - dt
22
+
23
+ seconds = diff.total_seconds()
24
+ if seconds < 60:
25
+ return "just now"
26
+ elif seconds < 3600:
27
+ minutes = int(seconds / 60)
28
+ return f"{minutes}m ago"
29
+ elif seconds < 86400:
30
+ hours = int(seconds / 3600)
31
+ return f"{hours}h ago"
32
+ elif seconds < 604800:
33
+ days = int(seconds / 86400)
34
+ return f"{days}d ago"
35
+ elif seconds < 2592000:
36
+ weeks = int(seconds / 604800)
37
+ return f"{weeks}w ago"
38
+ else:
39
+ return dt.strftime("%Y-%m-%d")
40
+ except Exception:
41
+ return timestamp[:10] if len(timestamp) >= 10 else timestamp
42
+
43
+
44
+ def get_visibility_badge(is_public: bool) -> Text:
45
+ """Create a visibility badge."""
46
+ if is_public:
47
+ return Text("● Public", style="green")
48
+ else:
49
+ return Text("○ Private", style="dim")
50
+
51
+
52
+ def format_stat(value: Optional[int], icon: str) -> str:
53
+ """Format a statistic with icon."""
54
+ return f"{icon} {value or 0}"
55
+
56
+
57
+ def display_notebooks_table(notebooks: List[Dict[str, Any]], console: Console) -> None:
58
+ """Display notebooks in a rich table."""
59
+ table = Table(show_header=True, header_style="bold", expand=True)
60
+ table.add_column("Title", style="cyan", no_wrap=False, ratio=3)
61
+ table.add_column("Organization", style="blue", no_wrap=True, ratio=1)
62
+ table.add_column("Status", justify="center", ratio=1)
63
+ table.add_column("Stats", justify="center", ratio=1)
64
+ table.add_column("Updated", justify="right", style="dim", ratio=1)
65
+
66
+ for notebook in notebooks:
67
+ title = notebook.get("title", "Untitled")
68
+ description = notebook.get("description", "")
69
+
70
+ # Build title cell with description
71
+ title_text = Text()
72
+ title_text.append(title, style="bold")
73
+ if description:
74
+ title_text.append(f"\n{description[:60]}{'...' if len(description) > 60 else ''}", style="dim")
75
+
76
+ # Organization
77
+ org = notebook.get("organizations", {})
78
+ org_name = org.get("name", "") if isinstance(org, dict) else ""
79
+
80
+ # Visibility
81
+ is_public = notebook.get("is_public", False)
82
+ visibility = get_visibility_badge(is_public)
83
+
84
+ # Stats
85
+ likes = notebook.get("like_count", 0) or 0
86
+ bookmarks = notebook.get("bookmark_count", 0) or 0
87
+ views = notebook.get("view_count", 0) or 0
88
+ stats = f"♥ {likes} ★ {bookmarks} 👁 {views}"
89
+
90
+ # Updated time
91
+ updated = format_relative_time(notebook.get("updated_at", ""))
92
+
93
+ table.add_row(title_text, org_name, visibility, stats, updated)
94
+
95
+ console.print(table)
96
+
97
+
98
+ def display_notebook_info(notebook: Dict[str, Any], console: Console) -> None:
99
+ """Display detailed notebook information in a panel."""
100
+ title = notebook.get("title", "Untitled")
101
+ description = notebook.get("description", "No description")
102
+ slug = notebook.get("slug", "")
103
+ is_public = notebook.get("is_public", False)
104
+
105
+ # Organization info
106
+ org = notebook.get("organizations", {})
107
+ org_name = org.get("name", "Unknown") if isinstance(org, dict) else "Unknown"
108
+ org_slug = org.get("slug", "") if isinstance(org, dict) else ""
109
+
110
+ # Stats
111
+ likes = notebook.get("like_count", 0) or 0
112
+ bookmarks = notebook.get("bookmark_count", 0) or 0
113
+ forks = notebook.get("fork_count", 0) or 0
114
+ views = notebook.get("view_count", 0) or 0
115
+
116
+ # Timestamps
117
+ created = format_relative_time(notebook.get("created_at", ""))
118
+ updated = format_relative_time(notebook.get("updated_at", ""))
119
+
120
+ # Tags
121
+ tags = notebook.get("tags", [])
122
+ tag_names = [t.get("name", "") for t in tags if isinstance(t, dict)]
123
+
124
+ # Build info text
125
+ info_lines = []
126
+ info_lines.append(f"[bold cyan]{title}[/bold cyan]")
127
+ info_lines.append("")
128
+ info_lines.append(f"[dim]{description}[/dim]")
129
+ info_lines.append("")
130
+ info_lines.append(f"[bold]Organization:[/bold] {org_name} [dim]({org_slug})[/dim]")
131
+ info_lines.append(f"[bold]Slug:[/bold] {slug}")
132
+ info_lines.append(f"[bold]Visibility:[/bold] {'Public' if is_public else 'Private'}")
133
+ info_lines.append("")
134
+
135
+ if tag_names:
136
+ tags_str = " ".join(f"[on blue] {t} [/on blue]" for t in tag_names)
137
+ info_lines.append(f"[bold]Tags:[/bold] {tags_str}")
138
+ info_lines.append("")
139
+
140
+ info_lines.append(f"[bold]Stats:[/bold] ♥ {likes} likes ★ {bookmarks} bookmarks 🔀 {forks} forks 👁 {views} views")
141
+ info_lines.append("")
142
+ info_lines.append(f"[bold]Created:[/bold] {created} [bold]Updated:[/bold] {updated}")
143
+
144
+ # User permissions
145
+ if notebook.get("can_edit"):
146
+ info_lines.append("")
147
+ info_lines.append("[green]✓ You can edit this notebook[/green]")
148
+
149
+ panel = Panel(
150
+ "\n".join(info_lines),
151
+ title="Notebook Info",
152
+ border_style="blue"
153
+ )
154
+ console.print(panel)
155
+
156
+
157
+ def display_notebook_preview(notebook: Dict[str, Any], console: Console,
158
+ max_cells: int = 20) -> None:
159
+ """Display notebook content preview with cells shown in terminal."""
160
+ # First show info
161
+ display_notebook_info(notebook, console)
162
+
163
+ content = notebook.get("content", {})
164
+ cells = content.get("cells", [])
165
+
166
+ if not cells:
167
+ console.print("\n[yellow]Notebook has no cells.[/yellow]")
168
+ return
169
+
170
+ # Summary
171
+ code_cells = sum(1 for c in cells if c.get("cell_type") == "code")
172
+ markdown_cells = sum(1 for c in cells if c.get("cell_type") == "markdown")
173
+
174
+ console.print(f"\n[bold]Cells:[/bold] {len(cells)} total ({code_cells} code, {markdown_cells} markdown)")
175
+
176
+ console.print("")
177
+ console.print(Rule("Cell Contents"))
178
+ console.print("")
179
+
180
+ for i, cell in enumerate(cells[:max_cells]):
181
+ cell_type = cell.get("cell_type", "unknown")
182
+ source = cell.get("source", [])
183
+
184
+ # Handle source as list or string
185
+ if isinstance(source, list):
186
+ source_text = "".join(source)
187
+ else:
188
+ source_text = str(source)
189
+
190
+ # Cell header
191
+ cell_icon = "📝" if cell_type == "markdown" else "💻" if cell_type == "code" else "❓"
192
+ console.print(f"[bold]{cell_icon} Cell {i + 1}[/bold] [dim]({cell_type})[/dim]")
193
+
194
+ if cell_type == "markdown":
195
+ # Render markdown
196
+ try:
197
+ md = Markdown(source_text[:500] + ("..." if len(source_text) > 500 else ""))
198
+ console.print(Panel(md, border_style="dim"))
199
+ except Exception:
200
+ console.print(Panel(source_text[:500], border_style="dim"))
201
+
202
+ elif cell_type == "code":
203
+ # Syntax highlight code
204
+ # Truncate very long cells
205
+ display_source = source_text[:1000]
206
+ if len(source_text) > 1000:
207
+ display_source += "\n... (truncated)"
208
+
209
+ try:
210
+ syntax = Syntax(display_source, "python", theme="monokai", line_numbers=True)
211
+ console.print(Panel(syntax, border_style="green"))
212
+ except Exception:
213
+ console.print(Panel(display_source, border_style="green"))
214
+
215
+ # Show outputs if any
216
+ outputs = cell.get("outputs", [])
217
+ if outputs:
218
+ console.print("[dim] Outputs:[/dim]")
219
+ for output in outputs[:3]: # Limit outputs shown
220
+ output_type = output.get("output_type", "")
221
+
222
+ if output_type == "stream":
223
+ text = output.get("text", [])
224
+ if isinstance(text, list):
225
+ text = "".join(text)
226
+ text = str(text)[:200]
227
+ console.print(f" [dim]{text}[/dim]")
228
+
229
+ elif output_type in ["execute_result", "display_data"]:
230
+ data = output.get("data", {})
231
+ if "text/plain" in data:
232
+ plain = data["text/plain"]
233
+ if isinstance(plain, list):
234
+ plain = "".join(plain)
235
+ plain = str(plain)[:200]
236
+ console.print(f" [cyan]{plain}[/cyan]")
237
+ elif "image/png" in data:
238
+ console.print(" [yellow]📊 [Image output][/yellow]")
239
+ elif "application/vnd.plotly.v1+json" in data:
240
+ console.print(" [yellow]📈 [Plotly chart][/yellow]")
241
+
242
+ elif output_type == "error":
243
+ ename = output.get("ename", "Error")
244
+ evalue = output.get("evalue", "")
245
+ console.print(f" [red]❌ {ename}: {evalue[:100]}[/red]")
246
+
247
+ console.print("")
248
+
249
+ if len(cells) > max_cells:
250
+ console.print(f"[dim]... and {len(cells) - max_cells} more cells. Use --max-cells to see more, or download the notebook.[/dim]")
251
+
252
+
253
+ def render_single_cell(cell: Dict[str, Any], index: int, total: int, console: Console) -> None:
254
+ """Render a single cell with its content and outputs."""
255
+ cell_type = cell.get("cell_type", "unknown")
256
+ source = cell.get("source", [])
257
+
258
+ # Handle source as list or string
259
+ if isinstance(source, list):
260
+ source_text = "".join(source)
261
+ else:
262
+ source_text = str(source)
263
+
264
+ # Clear screen and show header
265
+ console.clear()
266
+
267
+ # Header with navigation info
268
+ cell_icon = "📝" if cell_type == "markdown" else "💻" if cell_type == "code" else "❓"
269
+ header = Text()
270
+ header.append(f"{cell_icon} Cell {index + 1} of {total}", style="bold cyan")
271
+ header.append(f" ({cell_type})", style="dim")
272
+ console.print(header)
273
+ console.print()
274
+
275
+ if cell_type == "markdown":
276
+ # Render markdown
277
+ try:
278
+ md = Markdown(source_text)
279
+ console.print(Panel(md, border_style="blue", title="Markdown", title_align="left"))
280
+ except Exception:
281
+ console.print(Panel(source_text, border_style="blue", title="Markdown", title_align="left"))
282
+
283
+ elif cell_type == "code":
284
+ # Syntax highlight code
285
+ try:
286
+ syntax = Syntax(source_text, "python", theme="monokai", line_numbers=True)
287
+ console.print(Panel(syntax, border_style="green", title="Python", title_align="left"))
288
+ except Exception:
289
+ console.print(Panel(source_text, border_style="green", title="Code", title_align="left"))
290
+
291
+ # Show outputs if any
292
+ outputs = cell.get("outputs", [])
293
+ if outputs:
294
+ console.print()
295
+ console.print("[bold]Output:[/bold]")
296
+ for output in outputs:
297
+ output_type = output.get("output_type", "")
298
+
299
+ if output_type == "stream":
300
+ text = output.get("text", [])
301
+ if isinstance(text, list):
302
+ text = "".join(text)
303
+ console.print(Panel(str(text), border_style="dim", title=f"stdout", title_align="left"))
304
+
305
+ elif output_type in ["execute_result", "display_data"]:
306
+ data = output.get("data", {})
307
+ if "text/plain" in data:
308
+ plain = data["text/plain"]
309
+ if isinstance(plain, list):
310
+ plain = "".join(plain)
311
+ console.print(Panel(str(plain), border_style="cyan", title="Result", title_align="left"))
312
+ if "image/png" in data:
313
+ console.print("[yellow] 📊 [Image output - view in browser][/yellow]")
314
+ if "application/vnd.plotly.v1+json" in data:
315
+ console.print("[yellow] 📈 [Plotly chart - view in browser][/yellow]")
316
+
317
+ elif output_type == "error":
318
+ ename = output.get("ename", "Error")
319
+ evalue = output.get("evalue", "")
320
+ traceback = output.get("traceback", [])
321
+ error_text = f"{ename}: {evalue}"
322
+ if traceback:
323
+ # Clean ANSI codes from traceback
324
+ import re
325
+ clean_tb = "\n".join(re.sub(r'\x1b\[[0-9;]*m', '', line) for line in traceback[:5])
326
+ error_text = clean_tb
327
+ console.print(Panel(error_text, border_style="red", title="Error", title_align="left"))
328
+ else:
329
+ console.print(Panel(source_text[:500], border_style="yellow"))
330
+
331
+ # Footer with navigation hints
332
+ console.print()
333
+ nav_hints = Text()
334
+ if index > 0:
335
+ nav_hints.append("← ", style="bold")
336
+ nav_hints.append("prev ", style="dim")
337
+ if index < total - 1:
338
+ nav_hints.append("→ ", style="bold")
339
+ nav_hints.append("next ", style="dim")
340
+ nav_hints.append("q ", style="bold red")
341
+ nav_hints.append("quit", style="dim")
342
+ console.print(nav_hints)
343
+
344
+
345
+ def interactive_cell_viewer(cells: List[Dict[str, Any]], console: Console) -> None:
346
+ """Interactive viewer that allows scrolling through cells."""
347
+ if not cells:
348
+ console.print("[yellow]No cells in notebook.[/yellow]")
349
+ return
350
+
351
+ import sys
352
+
353
+ current_index = 0
354
+ total = len(cells)
355
+
356
+ # Platform-specific key reading
357
+ try:
358
+ import tty
359
+ import termios
360
+
361
+ def get_key():
362
+ """Read a single keypress (Unix)."""
363
+ fd = sys.stdin.fileno()
364
+ old_settings = termios.tcgetattr(fd)
365
+ try:
366
+ tty.setraw(fd)
367
+ ch = sys.stdin.read(1)
368
+ # Handle arrow keys (escape sequences)
369
+ if ch == '\x1b':
370
+ ch2 = sys.stdin.read(1)
371
+ if ch2 == '[':
372
+ ch3 = sys.stdin.read(1)
373
+ if ch3 == 'C': # Right arrow
374
+ return 'right'
375
+ elif ch3 == 'D': # Left arrow
376
+ return 'left'
377
+ elif ch3 == 'A': # Up arrow
378
+ return 'left'
379
+ elif ch3 == 'B': # Down arrow
380
+ return 'right'
381
+ return ch
382
+ finally:
383
+ termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
384
+ except ImportError:
385
+ # Windows fallback
386
+ try:
387
+ import msvcrt
388
+
389
+ def get_key():
390
+ """Read a single keypress (Windows)."""
391
+ ch = msvcrt.getch()
392
+ if ch in (b'\x00', b'\xe0'): # Special key prefix
393
+ ch2 = msvcrt.getch()
394
+ if ch2 == b'M': # Right arrow
395
+ return 'right'
396
+ elif ch2 == b'K': # Left arrow
397
+ return 'left'
398
+ elif ch2 == b'H': # Up arrow
399
+ return 'left'
400
+ elif ch2 == b'P': # Down arrow
401
+ return 'right'
402
+ return ch.decode('utf-8', errors='ignore')
403
+ except ImportError:
404
+ # Fallback to simple input
405
+ def get_key():
406
+ """Fallback key reading."""
407
+ return input("Press n/p/q: ").strip().lower()[:1] or 'n'
408
+
409
+ while True:
410
+ render_single_cell(cells[current_index], current_index, total, console)
411
+
412
+ try:
413
+ key = get_key()
414
+ except (KeyboardInterrupt, EOFError):
415
+ console.clear()
416
+ break
417
+
418
+ if key in ('q', 'Q', '\x03'): # q, Q, or Ctrl+C
419
+ console.clear()
420
+ break
421
+ elif key in ('right', 'n', 'j', ' ', '\r'): # Next
422
+ if current_index < total - 1:
423
+ current_index += 1
424
+ elif key in ('left', 'p', 'k'): # Previous
425
+ if current_index > 0:
426
+ current_index -= 1
427
+ elif key == 'g': # Go to first
428
+ current_index = 0
429
+ elif key == 'G': # Go to last
430
+ current_index = total - 1
431
+
432
+
433
+ def display_notebook_cell_summary(cells: List[Dict[str, Any]], console: Console) -> None:
434
+ """Display a summary of notebook cells."""
435
+ if not cells:
436
+ console.print("[yellow]No cells in notebook.[/yellow]")
437
+ return
438
+
439
+ table = Table(show_header=True, header_style="bold")
440
+ table.add_column("#", justify="right", style="dim")
441
+ table.add_column("Type", justify="center")
442
+ table.add_column("Preview", no_wrap=False)
443
+ table.add_column("Outputs", justify="center")
444
+
445
+ for i, cell in enumerate(cells[:30]):
446
+ cell_type = cell.get("cell_type", "unknown")
447
+ source = cell.get("source", [])
448
+ outputs = cell.get("outputs", [])
449
+
450
+ if isinstance(source, list):
451
+ source_text = "".join(source)
452
+ else:
453
+ source_text = str(source)
454
+
455
+ # Truncate preview
456
+ preview = source_text[:80].replace("\n", " ")
457
+ if len(source_text) > 80:
458
+ preview += "..."
459
+
460
+ type_style = "cyan" if cell_type == "markdown" else "green" if cell_type == "code" else "yellow"
461
+
462
+ table.add_row(
463
+ str(i + 1),
464
+ Text(cell_type, style=type_style),
465
+ preview,
466
+ str(len(outputs)) if outputs else "-"
467
+ )
468
+
469
+ console.print(table)
470
+
471
+ if len(cells) > 30:
472
+ console.print(f"\n[dim]Showing first 30 of {len(cells)} cells.[/dim]")
473
+
alphai/utils.py CHANGED
@@ -2,10 +2,77 @@
2
2
 
3
3
  import os
4
4
  import sys
5
+ import logging
5
6
  from typing import Dict, Any, Optional
6
7
  from pathlib import Path
7
8
  import json
8
9
  from datetime import datetime
10
+ from logging.handlers import RotatingFileHandler
11
+
12
+
13
+ def setup_logging(debug: bool = False) -> logging.Logger:
14
+ """Setup logging configuration for alphai.
15
+
16
+ Args:
17
+ debug: If True, set log level to DEBUG and output to console
18
+
19
+ Returns:
20
+ Configured logger instance
21
+ """
22
+ from .config import Config
23
+
24
+ log_dir = Config.get_config_dir() / "logs"
25
+ log_dir.mkdir(parents=True, exist_ok=True)
26
+
27
+ # Create logger
28
+ logger = logging.getLogger("alphai")
29
+ logger.setLevel(logging.DEBUG if debug else logging.INFO)
30
+
31
+ # Remove existing handlers to avoid duplicates
32
+ logger.handlers.clear()
33
+
34
+ # File handler with rotation (max 5 files of 10MB each)
35
+ log_file = log_dir / "alphai.log"
36
+ file_handler = RotatingFileHandler(
37
+ log_file,
38
+ maxBytes=10 * 1024 * 1024, # 10MB
39
+ backupCount=5
40
+ )
41
+ file_handler.setLevel(logging.DEBUG)
42
+ file_formatter = logging.Formatter(
43
+ '%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s'
44
+ )
45
+ file_handler.setFormatter(file_formatter)
46
+ logger.addHandler(file_handler)
47
+
48
+ # Console handler (only in debug mode)
49
+ if debug:
50
+ console_handler = logging.StreamHandler()
51
+ console_handler.setLevel(logging.DEBUG)
52
+ console_formatter = logging.Formatter(
53
+ '%(levelname)s - %(message)s'
54
+ )
55
+ console_handler.setFormatter(console_formatter)
56
+ logger.addHandler(console_handler)
57
+
58
+ # Prevent propagation to root logger
59
+ logger.propagate = False
60
+
61
+ logger.debug(f"Logging initialized. Debug mode: {debug}, Log file: {log_file}")
62
+
63
+ return logger
64
+
65
+
66
+ def get_logger(name: str = "alphai") -> logging.Logger:
67
+ """Get a logger instance.
68
+
69
+ Args:
70
+ name: Logger name (default: alphai)
71
+
72
+ Returns:
73
+ Logger instance
74
+ """
75
+ return logging.getLogger(name)
9
76
 
10
77
 
11
78
  def format_datetime(dt_string: Optional[str]) -> str:
@@ -1,28 +1,29 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alphai
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Summary: A CLI tool and Python package for the runalph.ai platform
5
- Author-email: American Data Science <support@americandatascience.com>
5
+ Author-email: Andrew Chang <andrew@runalph.ai>
6
6
  Project-URL: Homepage, https://runalph.ai
7
7
  Project-URL: Documentation, https://docs.runalph.ai
8
- Project-URL: Repository, https://github.com/americandatascience/alphai
9
- Project-URL: Issues, https://github.com/americandatascience/alphai/issues
8
+ Project-URL: Repository, https://github.com/alph-ai/alphai
9
+ Project-URL: Issues, https://github.com/alph-ai/alphai/issues
10
10
  Keywords: cli,api,data-science,alph
11
11
  Classifier: Development Status :: 4 - Beta
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
14
15
  Classifier: Programming Language :: Python :: 3.11
15
16
  Classifier: Programming Language :: Python :: 3.12
16
- Requires-Python: >=3.11
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Requires-Python: >=3.10
17
19
  Description-Content-Type: text/markdown
18
20
  Requires-Dist: click>=8.1.0
19
21
  Requires-Dist: rich>=13.0.0
20
- Requires-Dist: alph-sdk>=0.1.0
22
+ Requires-Dist: alph-sdk>=0.5.0
21
23
  Requires-Dist: httpx>=0.25.0
22
24
  Requires-Dist: pydantic>=2.0.0
23
- Requires-Dist: keyring>=24.0.0
24
- Requires-Dist: typer>=0.9.0
25
25
  Requires-Dist: questionary>=2.1.0
26
+ Requires-Dist: jupyterlab>=4.5.1
26
27
  Provides-Extra: dev
27
28
  Requires-Dist: pytest>=7.0.0; extra == "dev"
28
29
  Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
@@ -0,0 +1,23 @@
1
+ alphai/__init__.py,sha256=bqujmQ7WrxKzmGVS_QFOJCTFi3u1EFzV4eaxiBv7uSE,1063
2
+ alphai/auth.py,sha256=rmMlikW9M0wVlNb8FXixrvcemPLaKXFO3Ocaiijjge8,15589
3
+ alphai/cleanup.py,sha256=JEgysHuvK0sR1X4M5u0mBdKB8Kz1KIyF7fhW0i4uU0Q,12250
4
+ alphai/cli.py,sha256=HTSqjDOJPAGj4WqsCFavjUEGqx4rzQ_a6CahhfRyU04,4660
5
+ alphai/client.py,sha256=RD6XnpBkHaJY2pqOxIouEHZxUmkSVVfg_43oIrbK8wA,18892
6
+ alphai/config.py,sha256=b6494qVN_lN2Xuy64W7Ceo5fAnP5f97Z2wH5-lIHMQQ,3449
7
+ alphai/docker.py,sha256=t86SnK2_QeQjqn3yisWLod5DBlDOAF05qpEZcFxYZD8,32387
8
+ alphai/exceptions.py,sha256=ShSHxwc7WnsMu2ugRUxNgF4C9bipKu0_PvfoK7591dE,3401
9
+ alphai/jupyter_manager.py,sha256=DFhXGpDsWq3UE7A1TckLjlGDCJL3AYjKnW5-Ru6su1o,23712
10
+ alphai/notebook_renderer.py,sha256=RFaoUnicMYfTUJOd2dUQjab-ZBpomyK5RbpbjiGBBjU,18393
11
+ alphai/utils.py,sha256=-zqDCRBS_D20xGzRCN-BVuwyt1jmF2-A6Y4_arOTvUE,7651
12
+ alphai/commands/__init__.py,sha256=8ZFsPVBcT4KqgVv7xLI_uiv_Sb2FGDyStFF5Gcsjnd4,528
13
+ alphai/commands/config.py,sha256=y_kIxoC7t0TV5pRVYP5pKCDz2xWybWv43PeA1R07L80,1780
14
+ alphai/commands/docker.py,sha256=alDM2ZBhGGHRgayIwPz3gKkX8dLIPzNrBXlHq2_qi7s,23782
15
+ alphai/commands/jupyter.py,sha256=UzKZvloB0J4iwri59PZ_EK_imXjKVDGvG4hyAUJ24Pk,13367
16
+ alphai/commands/notebooks.py,sha256=flYKfVVTvlooB1ijFmSJLlK-j28RiphmCAP7JNbFl80,43264
17
+ alphai/commands/orgs.py,sha256=qhcuXXTCfwxspe3SAgpaITyyqPye2747jPNz91ysHv4,735
18
+ alphai/commands/projects.py,sha256=-udwF_cew5DUR9m_BhHjjm2cFEJb1HBtWeiKdzrNPlQ,988
19
+ alphai-0.2.0.dist-info/METADATA,sha256=6x3WJ2pDWmrQxuxcvlclcJnJY5GtP_OdI1MgO0fV9S8,9634
20
+ alphai-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
21
+ alphai-0.2.0.dist-info/entry_points.txt,sha256=ITOwv5erK-gjYw47KsOoENHvIAUW_ynEsEMLZ7GHZwA,43
22
+ alphai-0.2.0.dist-info/top_level.txt,sha256=dFmybyT4Kzcgpsccun8RnBxkm9lK0Y0TPfaVe2FyxNY,7
23
+ alphai-0.2.0.dist-info/RECORD,,
@@ -1,12 +0,0 @@
1
- alphai/__init__.py,sha256=3qW-BaHhXUKB-PfTfUzHguwN-LuXaRhbWlev3P8YmFE,294
2
- alphai/auth.py,sha256=fk6Ow7GwL8xbK03bKyiyT9XMUXXJllJe9XqWv-ENXrs,14283
3
- alphai/cli.py,sha256=nWE0I7bkDRkbfCYnvXu3qsvvoWoQ87ryX98MUG9CttE,38779
4
- alphai/client.py,sha256=Q5N9WdOB0eGUTZeNQPBMBj7kI13TbjPQfGlEJLQvFKg,16042
5
- alphai/config.py,sha256=Mp8DJt0CDF_holnHDHzfCs7uRkgSCAQOkLNqGPnKKyo,3143
6
- alphai/docker.py,sha256=eLTYmO1NFhTOsn7ZTE1DggVIJKrsnzOgRSCHwXpxkp4,30294
7
- alphai/utils.py,sha256=tXGoaIjM1RAXKsjEQ0PjA9vrM-KFf5DCQ8DB83peVBU,5718
8
- alphai-0.1.1.dist-info/METADATA,sha256=1Lhg2O70nc61P8G4yF-3IjoL2XULvix7DsXPhf2hCcc,9605
9
- alphai-0.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
10
- alphai-0.1.1.dist-info/entry_points.txt,sha256=ITOwv5erK-gjYw47KsOoENHvIAUW_ynEsEMLZ7GHZwA,43
11
- alphai-0.1.1.dist-info/top_level.txt,sha256=dFmybyT4Kzcgpsccun8RnBxkm9lK0Y0TPfaVe2FyxNY,7
12
- alphai-0.1.1.dist-info/RECORD,,
File without changes