streamwright 0.1.7__tar.gz → 0.1.8__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.
- {streamwright-0.1.7/src/streamwright.egg-info → streamwright-0.1.8}/PKG-INFO +1 -1
- {streamwright-0.1.7 → streamwright-0.1.8}/pyproject.toml +1 -1
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/cli.py +51 -17
- {streamwright-0.1.7 → streamwright-0.1.8/src/streamwright.egg-info}/PKG-INFO +1 -1
- streamwright-0.1.8/tests/test_cli_subcommands.py +72 -0
- streamwright-0.1.7/tests/test_cli_subcommands.py +0 -32
- {streamwright-0.1.7 → streamwright-0.1.8}/LICENSE +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/README.md +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/setup.cfg +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/setup.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/__init__.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/catalog.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/config/__init__.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/config/inputs.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/config/loader.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/config/reader.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/engine/__init__.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/engine/queries.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/engine/runner.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/engine/sql.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/net/__init__.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/net/downloads.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/net/encoding.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/net/http.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/net/paginators.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/outputs/__init__.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/outputs/dlt_output.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/outputs/exporter.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/outputs/output.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/outputs/staging.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/outputs/warehouse.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/runtime/__init__.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/runtime/components.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/runtime/logs.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/runtime/templates.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/runtime/testing.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/validation/__init__.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/validation/engine.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/validation/schema.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright/core/validation/source.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright.egg-info/SOURCES.txt +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright.egg-info/dependency_links.txt +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright.egg-info/entry_points.txt +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright.egg-info/requires.txt +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/src/streamwright.egg-info/top_level.txt +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/tests/test_catalog.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/tests/test_connectors.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/tests/test_dlt_output.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/tests/test_exact_decimals.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/tests/test_exporter.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/tests/test_http_engine.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/tests/test_logging.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/tests/test_output_formats.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/tests/test_runner.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/tests/test_sql.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/tests/test_transform.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/tests/test_validation.py +0 -0
- {streamwright-0.1.7 → streamwright-0.1.8}/tests/test_warehouse_output.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: streamwright
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.8
|
|
4
4
|
Summary: Declarative data connectors — pull from APIs, files and databases with YAML, shape with SQL, write anywhere.
|
|
5
5
|
Author-email: Karthick Jaganathan <kjaganathan.sde@gmail.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "streamwright"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.8"
|
|
8
8
|
description = "Declarative data connectors — pull from APIs, files and databases with YAML, shape with SQL, write anywhere."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = {text = "Apache-2.0"}
|
|
@@ -241,12 +241,18 @@ def _parser():
|
|
|
241
241
|
_add_log_options(run)
|
|
242
242
|
|
|
243
243
|
conn = commands.add_parser("connectors",
|
|
244
|
-
help="list,
|
|
244
|
+
help="list, find or install connectors (bare: the installed connectors and their "
|
|
245
245
|
"SDK loggers)")
|
|
246
|
-
conn.add_argument("
|
|
247
|
-
help="list
|
|
246
|
+
conn.add_argument("-ls", "--list", action="store_true", dest="flag_list",
|
|
247
|
+
help="list catalog and installed connectors")
|
|
248
|
+
conn.add_argument("-i", "--install", nargs="+", dest="flag_install", metavar="KEY",
|
|
249
|
+
help="install one or more connector keys")
|
|
250
|
+
conn.add_argument("-s", "-f", "--search", "--find", nargs="+", dest="flag_search", metavar="TEXT",
|
|
251
|
+
help="find/search connectors in the catalog by keyword")
|
|
252
|
+
conn.add_argument("action", nargs="?", metavar="{ls,i,find}",
|
|
253
|
+
help="ls (catalog + installed), -i KEY (install), or find TEXT (search catalog)")
|
|
248
254
|
conn.add_argument("query", nargs="*", metavar="KEY|TEXT",
|
|
249
|
-
help="connector keys (install: one or more) or words
|
|
255
|
+
help="connector keys (install: one or more) or search words")
|
|
250
256
|
conn.add_argument("--yes", action="store_true", help="skip the confirmation prompt when installing")
|
|
251
257
|
conn.add_argument("--hub-url", metavar="URL",
|
|
252
258
|
help="the connector hub (default: $STREAMWRIGHT_HUB_URL, else the live StreamWright hub; when it is "
|
|
@@ -562,19 +568,42 @@ def _connector_lines():
|
|
|
562
568
|
|
|
563
569
|
|
|
564
570
|
def _connectors_command(args):
|
|
565
|
-
"""`streamwright connectors`: bare = installed list;
|
|
566
|
-
|
|
571
|
+
"""`streamwright connectors`: bare = installed list; ls/i/find use the catalog (the hub)."""
|
|
572
|
+
if getattr(args, "flag_list", False):
|
|
573
|
+
action = "ls"
|
|
574
|
+
query = []
|
|
575
|
+
elif getattr(args, "flag_install", None):
|
|
576
|
+
action = "install"
|
|
577
|
+
query = args.flag_install
|
|
578
|
+
elif getattr(args, "flag_search", None):
|
|
579
|
+
action = "find"
|
|
580
|
+
query = args.flag_search
|
|
581
|
+
else:
|
|
582
|
+
action = getattr(args, "action", None)
|
|
583
|
+
query = getattr(args, "query", [])
|
|
584
|
+
|
|
567
585
|
if action is None:
|
|
568
586
|
lines = _connector_lines()
|
|
569
|
-
print("\n".join(lines) if lines else "no connectors installed (e.g. streamwright connectors
|
|
587
|
+
print("\n".join(lines) if lines else "no connectors installed (e.g. streamwright connectors -i postgres)")
|
|
570
588
|
return 0
|
|
571
|
-
|
|
572
|
-
|
|
589
|
+
|
|
590
|
+
norm_action = action.lower()
|
|
591
|
+
if norm_action in ("ls", "list", "-ls", "--list"):
|
|
592
|
+
from streamwright.core import catalog
|
|
573
593
|
lines = catalog.listing(args.hub_url)
|
|
574
594
|
print("\n".join(lines) if lines else "the catalog is empty")
|
|
575
595
|
return 0
|
|
576
|
-
|
|
577
|
-
|
|
596
|
+
|
|
597
|
+
if norm_action in ("i", "install", "-i", "--install"):
|
|
598
|
+
from streamwright.core import catalog
|
|
599
|
+
if not query:
|
|
600
|
+
sys.stderr.write("streamwright: 'connectors -i' needs at least one connector KEY\n")
|
|
601
|
+
return 2
|
|
602
|
+
return catalog.install_many(query, assume_yes=args.yes, hub_url=args.hub_url)
|
|
603
|
+
|
|
604
|
+
if norm_action in ("find", "search", "s", "-s", "-f", "--find", "--search"):
|
|
605
|
+
from streamwright.core import catalog
|
|
606
|
+
text = " ".join(query)
|
|
578
607
|
hits = catalog.search(text, args.hub_url)
|
|
579
608
|
if not hits:
|
|
580
609
|
print("no connectors match %r" % text)
|
|
@@ -582,12 +611,17 @@ def _connectors_command(args):
|
|
|
582
611
|
for key, entry in sorted(hits.items()):
|
|
583
612
|
print(" %-16s %-10s %s" % (key, entry.get("trust", "community"), entry.get("summary", "")))
|
|
584
613
|
return 0
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
614
|
+
|
|
615
|
+
# If action was not a reserved verb, treat it as a direct search query (e.g. `sw connectors ads`)
|
|
616
|
+
from streamwright.core import catalog
|
|
617
|
+
text = " ".join([action] + query)
|
|
618
|
+
hits = catalog.search(text, args.hub_url)
|
|
619
|
+
if not hits:
|
|
620
|
+
print("no connectors match %r" % text)
|
|
621
|
+
return 0
|
|
622
|
+
for key, entry in sorted(hits.items()):
|
|
623
|
+
print(" %-16s %-10s %s" % (key, entry.get("trust", "community"), entry.get("summary", "")))
|
|
624
|
+
return 0
|
|
591
625
|
|
|
592
626
|
|
|
593
627
|
def main(argv=None):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: streamwright
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.8
|
|
4
4
|
Summary: Declarative data connectors — pull from APIs, files and databases with YAML, shape with SQL, write anywhere.
|
|
5
5
|
Author-email: Karthick Jaganathan <kjaganathan.sde@gmail.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import sys
|
|
3
|
+
from unittest.mock import patch
|
|
4
|
+
|
|
5
|
+
from streamwright.core import cli
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_cli_help():
|
|
9
|
+
result = subprocess.run([sys.executable, "-m", "streamwright.core.cli", "--help"],
|
|
10
|
+
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
|
11
|
+
universal_newlines=True)
|
|
12
|
+
assert result.returncode == 0
|
|
13
|
+
assert "mcp" in result.stdout
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_cli_mcp_delegation():
|
|
17
|
+
from unittest.mock import MagicMock
|
|
18
|
+
mock_mcp = MagicMock(return_value=0)
|
|
19
|
+
mock_mod = MagicMock(main=mock_mcp)
|
|
20
|
+
with patch.dict(sys.modules, {"streamwright_mcp": MagicMock(), "streamwright_mcp.cli": mock_mod}):
|
|
21
|
+
code = cli.main(["mcp", "--help"])
|
|
22
|
+
assert code == 0
|
|
23
|
+
mock_mcp.assert_called_once_with(["--help"])
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def test_cli_mcp_not_installed(capsys):
|
|
27
|
+
with patch.dict(sys.modules, {"streamwright_mcp.cli": None}):
|
|
28
|
+
with patch("builtins.__import__", side_effect=ImportError("No module named 'streamwright_mcp'")):
|
|
29
|
+
code = cli.main(["mcp"])
|
|
30
|
+
assert code == 1
|
|
31
|
+
captured = capsys.readouterr()
|
|
32
|
+
assert "'streamwright-mcp' is not installed" in captured.err
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_cli_connectors_help():
|
|
36
|
+
result = subprocess.run([sys.executable, "-m", "streamwright.core.cli", "connectors", "--help"],
|
|
37
|
+
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
|
38
|
+
universal_newlines=True)
|
|
39
|
+
assert result.returncode == 0
|
|
40
|
+
assert "-ls" in result.stdout
|
|
41
|
+
assert "-i" in result.stdout
|
|
42
|
+
assert "-s" in result.stdout or "find" in result.stdout
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_cli_connectors_variants(monkeypatch, capsys):
|
|
46
|
+
from streamwright.core import catalog
|
|
47
|
+
fake_catalog = {
|
|
48
|
+
"postgres": {"title": "Postgres", "summary": "Postgres DB", "trust": "official"}
|
|
49
|
+
}
|
|
50
|
+
monkeypatch.setattr(catalog, "connectors", lambda hub_url=None: fake_catalog)
|
|
51
|
+
monkeypatch.setattr(catalog, "listing", lambda hub_url=None: ["catalog-listing-item"])
|
|
52
|
+
|
|
53
|
+
# Test ls subcommand
|
|
54
|
+
code = cli.main(["connectors", "ls"])
|
|
55
|
+
assert code == 0
|
|
56
|
+
assert "catalog-listing-item" in capsys.readouterr().out
|
|
57
|
+
|
|
58
|
+
# Test -ls flag
|
|
59
|
+
code = cli.main(["connectors", "-ls"])
|
|
60
|
+
assert code == 0
|
|
61
|
+
assert "catalog-listing-item" in capsys.readouterr().out
|
|
62
|
+
|
|
63
|
+
# Test find subcommand
|
|
64
|
+
code = cli.main(["connectors", "find", "postgres"])
|
|
65
|
+
assert code == 0
|
|
66
|
+
assert "postgres" in capsys.readouterr().out
|
|
67
|
+
|
|
68
|
+
# Test -s flag
|
|
69
|
+
code = cli.main(["connectors", "-s", "postgres"])
|
|
70
|
+
assert code == 0
|
|
71
|
+
assert "postgres" in capsys.readouterr().out
|
|
72
|
+
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import subprocess
|
|
2
|
-
import sys
|
|
3
|
-
from unittest.mock import patch
|
|
4
|
-
|
|
5
|
-
from streamwright.core import cli
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
def test_cli_help():
|
|
9
|
-
result = subprocess.run([sys.executable, "-m", "streamwright.core.cli", "--help"],
|
|
10
|
-
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
|
11
|
-
universal_newlines=True)
|
|
12
|
-
assert result.returncode == 0
|
|
13
|
-
assert "mcp" in result.stdout
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def test_cli_mcp_delegation():
|
|
17
|
-
from unittest.mock import MagicMock
|
|
18
|
-
mock_mcp = MagicMock(return_value=0)
|
|
19
|
-
mock_mod = MagicMock(main=mock_mcp)
|
|
20
|
-
with patch.dict(sys.modules, {"streamwright_mcp": MagicMock(), "streamwright_mcp.cli": mock_mod}):
|
|
21
|
-
code = cli.main(["mcp", "--help"])
|
|
22
|
-
assert code == 0
|
|
23
|
-
mock_mcp.assert_called_once_with(["--help"])
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def test_cli_mcp_not_installed(capsys):
|
|
27
|
-
with patch.dict(sys.modules, {"streamwright_mcp.cli": None}):
|
|
28
|
-
with patch("builtins.__import__", side_effect=ImportError("No module named 'streamwright_mcp'")):
|
|
29
|
-
code = cli.main(["mcp"])
|
|
30
|
-
assert code == 1
|
|
31
|
-
captured = capsys.readouterr()
|
|
32
|
-
assert "'streamwright-mcp' is not installed" in captured.err
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|