steve-cli 0.3.8__tar.gz → 0.3.9__tar.gz

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.
Files changed (44) hide show
  1. {steve_cli-0.3.8 → steve_cli-0.3.9}/PKG-INFO +4 -1
  2. {steve_cli-0.3.8 → steve_cli-0.3.9}/pyproject.toml +5 -1
  3. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/cli.py +40 -3
  4. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/decorators/lineage_job.py +4 -3
  5. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/lineage/collector.py +5 -1
  6. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli.egg-info/PKG-INFO +4 -1
  7. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli.egg-info/requires.txt +4 -0
  8. {steve_cli-0.3.8 → steve_cli-0.3.9}/README.md +0 -0
  9. {steve_cli-0.3.8 → steve_cli-0.3.9}/setup.cfg +0 -0
  10. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/__init__.py +0 -0
  11. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/decorators/__init__.py +0 -0
  12. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/lineage/__init__.py +0 -0
  13. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/lineage/adapters/__init__.py +0 -0
  14. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/lineage/adapters/logging.py +0 -0
  15. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/lineage/adapters/null.py +0 -0
  16. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/lineage/adapters/openlineage.py +0 -0
  17. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/lineage/port.py +0 -0
  18. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/lineage/registry.py +0 -0
  19. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/lineage/storage.py +0 -0
  20. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/storage/__init__.py +0 -0
  21. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/storage/metadata/__init__.py +0 -0
  22. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/storage/metadata/extractors/__init__.py +0 -0
  23. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/storage/metadata/extractors/csv.py +0 -0
  24. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/storage/metadata/extractors/excel.py +0 -0
  25. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/storage/metadata/extractors/generic.py +0 -0
  26. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/storage/metadata/extractors/json.py +0 -0
  27. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/storage/metadata/extractors/parquet.py +0 -0
  28. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/storage/metadata/port.py +0 -0
  29. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/storage/metadata/registry.py +0 -0
  30. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/storage/parquet.py +0 -0
  31. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/storage/protocol.py +0 -0
  32. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/storage/s3.py +0 -0
  33. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/storage.py +0 -0
  34. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/validation/__init__.py +0 -0
  35. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/validation/adapters/__init__.py +0 -0
  36. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/validation/adapters/great_expectations.py +0 -0
  37. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/validation/adapters/null.py +0 -0
  38. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/validation/adapters/validoopsie.py +0 -0
  39. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/validation/port.py +0 -0
  40. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli/validation/registry.py +0 -0
  41. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli.egg-info/SOURCES.txt +0 -0
  42. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli.egg-info/dependency_links.txt +0 -0
  43. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli.egg-info/entry_points.txt +0 -0
  44. {steve_cli-0.3.8 → steve_cli-0.3.9}/steve_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: steve-cli
3
- Version: 0.3.8
3
+ Version: 0.3.9
4
4
  Summary: A simple CLI tool to run jobs from jobs.yaml with proper environment setup
5
5
  Author: Frank
6
6
  License: MIT
@@ -44,6 +44,8 @@ Requires-Dist: great-expectations>=0.18.0; extra == "great-expectations"
44
44
  Requires-Dist: pandas>=2.0.3; extra == "great-expectations"
45
45
  Provides-Extra: excel
46
46
  Requires-Dist: openpyxl>=3.1.0; extra == "excel"
47
+ Provides-Extra: visidata
48
+ Requires-Dist: visidata>=3.0; extra == "visidata"
47
49
  Provides-Extra: all
48
50
  Requires-Dist: openlineage-python>=1.0.0; extra == "all"
49
51
  Requires-Dist: pyarrow>=17.0.0; extra == "all"
@@ -52,6 +54,7 @@ Requires-Dist: validoopsie>=0.1.0; extra == "all"
52
54
  Requires-Dist: great-expectations>=0.18.0; extra == "all"
53
55
  Requires-Dist: pandas>=2.0.3; extra == "all"
54
56
  Requires-Dist: openpyxl>=3.1.0; extra == "all"
57
+ Requires-Dist: visidata>=3.0; extra == "all"
55
58
 
56
59
  # Steve CLI
57
60
 
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
 
6
6
  [project]
7
7
  name = "steve-cli"
8
- version = "0.3.8"
8
+ version = "0.3.9"
9
9
  description = "A simple CLI tool to run jobs from jobs.yaml with proper environment setup"
10
10
  readme = "README.md"
11
11
  license = {text = "MIT"}
@@ -60,6 +60,9 @@ great-expectations = [
60
60
  excel = [
61
61
  "openpyxl>=3.1.0",
62
62
  ]
63
+ visidata = [
64
+ "visidata>=3.0",
65
+ ]
63
66
  all = [
64
67
  "openlineage-python>=1.0.0",
65
68
  "pyarrow>=17.0.0",
@@ -68,6 +71,7 @@ all = [
68
71
  "great-expectations>=0.18.0",
69
72
  "pandas>=2.0.3",
70
73
  "openpyxl>=3.1.0",
74
+ "visidata>=3.0",
71
75
  ]
72
76
 
73
77
  [project.scripts]
@@ -9,6 +9,7 @@ Usage:
9
9
  """
10
10
 
11
11
  import os
12
+ import shutil
12
13
  import signal
13
14
  import socket
14
15
  import subprocess
@@ -18,7 +19,7 @@ from pathlib import Path
18
19
  from typing import Dict, List, Any, Optional
19
20
 
20
21
  import click
21
- from dotenv import load_dotenv
22
+ from dotenv import load_dotenv, dotenv_values
22
23
  import questionary
23
24
  import yaml
24
25
 
@@ -69,6 +70,10 @@ def run_job_command(job: Dict[str, Any]) -> int:
69
70
  return 1
70
71
 
71
72
  env = os.environ.copy()
73
+ for env_filename in [".env", ".workspaces.env"]:
74
+ env_path = Path.cwd() / env_filename
75
+ if env_path.exists():
76
+ env.update({k: v for k, v in dotenv_values(env_path).items() if v is not None})
72
77
  job_env = job.get('env', {})
73
78
  for key, value in job_env.items():
74
79
  env[key] = str(value)
@@ -369,6 +374,10 @@ def apps_start(app_name: str, apps_file: Optional[Path]):
369
374
  sys.exit(1)
370
375
 
371
376
  env = os.environ.copy()
377
+ for env_filename in [".env", ".workspaces.env"]:
378
+ env_path = config.apps_file.parent / env_filename
379
+ if env_path.exists():
380
+ env.update({k: v for k, v in dotenv_values(env_path).items() if v is not None})
372
381
  for key, value in env_vars.items():
373
382
  env[key] = str(value)
374
383
 
@@ -537,7 +546,7 @@ def _print_tree(node: Dict[str, Any], prefix: str = "", is_last: bool = True) ->
537
546
  _print_tree(child, prefix + extension, last)
538
547
 
539
548
 
540
- def _list_bucket(storage_kwargs: dict, label: str, bucket_name: str) -> None:
549
+ def _list_bucket(storage_kwargs: dict, label: str, bucket_name: str) -> tuple:
541
550
  click.echo(f" {click.style(label, fg='cyan')} ({bucket_name})")
542
551
  try:
543
552
  from steve_cli.storage import S3Storage
@@ -548,10 +557,12 @@ def _list_bucket(storage_kwargs: dict, label: str, bucket_name: str) -> None:
548
557
  else:
549
558
  tree = _build_tree(keys)
550
559
  _print_tree(tree, prefix=" ")
560
+ return storage, keys
551
561
  except EnvironmentError as e:
552
562
  click.echo(f" ⚠️ {e}", err=True)
553
563
  except Exception as e:
554
564
  click.echo(f" ❌ {e}", err=True)
565
+ return None, []
555
566
 
556
567
 
557
568
  @main.command("buckets")
@@ -602,7 +613,33 @@ def buckets(env_file: tuple):
602
613
  sys.exit(0)
603
614
 
604
615
  selected = next(o for o in options if o["label"] == choice)
605
- _list_bucket(selected["kwargs"], selected["tier"], selected["bucket_name"])
616
+ storage, keys = _list_bucket(selected["kwargs"], selected["tier"], selected["bucket_name"])
617
+
618
+ if not storage or not keys:
619
+ return
620
+
621
+ file_choice = questionary.select(
622
+ "View a file (or press Esc to exit):",
623
+ choices=["(done)"] + keys,
624
+ ).ask()
625
+
626
+ if not file_choice or file_choice == "(done)":
627
+ return
628
+
629
+ click.echo(f"\n📄 {click.style(file_choice, fg='cyan')}\n")
630
+ try:
631
+ import tempfile
632
+ data = storage.get_bytes(file_choice)
633
+ suffix = Path(file_choice).suffix
634
+ with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as tmp:
635
+ tmp.write(data)
636
+ tmp_path = tmp.name
637
+ if not shutil.which("vd"):
638
+ click.secho("visidata not found. Install it with: uv pip install 'steve-cli[visidata]'", fg="yellow")
639
+ return
640
+ subprocess.call(["vd", tmp_path])
641
+ except Exception as e:
642
+ click.secho(f"❌ Could not open file: {e}", fg="red", err=True)
606
643
 
607
644
 
608
645
  if __name__ == '__main__':
@@ -45,10 +45,11 @@ def lineage_job(
45
45
  result = fn(*args, get_storage=get_storage, **kwargs)
46
46
  except Exception as exc:
47
47
  session.fail(exc)
48
+ import sys
48
49
  from steve_cli.validation.port import DataQualityError
49
- if isinstance(exc, DataQualityError):
50
- import sys
51
- print(f"ERROR {exc}", file=sys.stderr)
50
+ if isinstance(exc, (DataQualityError, EnvironmentError)):
51
+ import click
52
+ click.secho(f"ERROR {exc}", fg="red", bold=True, err=True)
52
53
  sys.exit(1)
53
54
  raise
54
55
 
@@ -86,7 +86,11 @@ def make_session(
86
86
  kwargs = {"url": url} if prov == "openlineage" else {}
87
87
  try:
88
88
  port = LineageRegistry.create(prov, **kwargs)
89
- except Exception:
89
+ except Exception as exc:
90
+ import logging
91
+ logging.getLogger(__name__).warning(
92
+ "Lineage disabled: could not initialize provider %r: %s", prov, exc
93
+ )
90
94
  from .adapters.null import NullLineageAdapter
91
95
 
92
96
  port = NullLineageAdapter()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: steve-cli
3
- Version: 0.3.8
3
+ Version: 0.3.9
4
4
  Summary: A simple CLI tool to run jobs from jobs.yaml with proper environment setup
5
5
  Author: Frank
6
6
  License: MIT
@@ -44,6 +44,8 @@ Requires-Dist: great-expectations>=0.18.0; extra == "great-expectations"
44
44
  Requires-Dist: pandas>=2.0.3; extra == "great-expectations"
45
45
  Provides-Extra: excel
46
46
  Requires-Dist: openpyxl>=3.1.0; extra == "excel"
47
+ Provides-Extra: visidata
48
+ Requires-Dist: visidata>=3.0; extra == "visidata"
47
49
  Provides-Extra: all
48
50
  Requires-Dist: openlineage-python>=1.0.0; extra == "all"
49
51
  Requires-Dist: pyarrow>=17.0.0; extra == "all"
@@ -52,6 +54,7 @@ Requires-Dist: validoopsie>=0.1.0; extra == "all"
52
54
  Requires-Dist: great-expectations>=0.18.0; extra == "all"
53
55
  Requires-Dist: pandas>=2.0.3; extra == "all"
54
56
  Requires-Dist: openpyxl>=3.1.0; extra == "all"
57
+ Requires-Dist: visidata>=3.0; extra == "all"
55
58
 
56
59
  # Steve CLI
57
60
 
@@ -12,6 +12,7 @@ validoopsie>=0.1.0
12
12
  great-expectations>=0.18.0
13
13
  pandas>=2.0.3
14
14
  openpyxl>=3.1.0
15
+ visidata>=3.0
15
16
 
16
17
  [dev]
17
18
  pytest>=7.0
@@ -43,3 +44,6 @@ pyarrow>=17.0.0
43
44
  [validoopsie]
44
45
  validoopsie>=0.1.0
45
46
  polars>=1.8.2
47
+
48
+ [visidata]
49
+ visidata>=3.0
File without changes
File without changes