aptdata 0.0.2__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.
Files changed (65) hide show
  1. aptdata/__init__.py +3 -0
  2. aptdata/cli/__init__.py +5 -0
  3. aptdata/cli/app.py +247 -0
  4. aptdata/cli/commands/__init__.py +9 -0
  5. aptdata/cli/commands/config_cmd.py +128 -0
  6. aptdata/cli/commands/mesh_cmd.py +435 -0
  7. aptdata/cli/commands/plugin_cmd.py +107 -0
  8. aptdata/cli/commands/system_cmd.py +90 -0
  9. aptdata/cli/commands/telemetry_cmd.py +57 -0
  10. aptdata/cli/completions.py +56 -0
  11. aptdata/cli/interactive.py +269 -0
  12. aptdata/cli/rendering/__init__.py +31 -0
  13. aptdata/cli/rendering/console.py +119 -0
  14. aptdata/cli/rendering/logger.py +26 -0
  15. aptdata/cli/rendering/panels.py +87 -0
  16. aptdata/cli/rendering/tables.py +81 -0
  17. aptdata/cli/scaffold.py +1089 -0
  18. aptdata/config/__init__.py +13 -0
  19. aptdata/config/parser.py +136 -0
  20. aptdata/config/schema.py +27 -0
  21. aptdata/config/secrets.py +60 -0
  22. aptdata/core/__init__.py +46 -0
  23. aptdata/core/context.py +31 -0
  24. aptdata/core/dataset.py +39 -0
  25. aptdata/core/lineage.py +213 -0
  26. aptdata/core/state.py +27 -0
  27. aptdata/core/system.py +317 -0
  28. aptdata/core/workflow.py +372 -0
  29. aptdata/mcp/__init__.py +5 -0
  30. aptdata/mcp/server.py +198 -0
  31. aptdata/plugins/__init__.py +77 -0
  32. aptdata/plugins/ai/__init__.py +6 -0
  33. aptdata/plugins/ai/chunking.py +66 -0
  34. aptdata/plugins/ai/embeddings.py +56 -0
  35. aptdata/plugins/base.py +57 -0
  36. aptdata/plugins/dataset.py +62 -0
  37. aptdata/plugins/governance/__init__.py +32 -0
  38. aptdata/plugins/governance/catalog.py +115 -0
  39. aptdata/plugins/governance/classification.py +44 -0
  40. aptdata/plugins/governance/lineage_store.py +49 -0
  41. aptdata/plugins/governance/rules.py +180 -0
  42. aptdata/plugins/local_fs.py +241 -0
  43. aptdata/plugins/manager.py +142 -0
  44. aptdata/plugins/postgres.py +113 -0
  45. aptdata/plugins/quality/__init__.py +39 -0
  46. aptdata/plugins/quality/contract.py +128 -0
  47. aptdata/plugins/quality/expectations.py +310 -0
  48. aptdata/plugins/quality/report.py +94 -0
  49. aptdata/plugins/quality/validator.py +139 -0
  50. aptdata/plugins/rest.py +135 -0
  51. aptdata/plugins/transform/__init__.py +14 -0
  52. aptdata/plugins/transform/pandas.py +129 -0
  53. aptdata/plugins/transform/spark.py +134 -0
  54. aptdata/plugins/vector/__init__.py +6 -0
  55. aptdata/plugins/vector/base.py +19 -0
  56. aptdata/plugins/vector/qdrant.py +41 -0
  57. aptdata/telemetry/__init__.py +5 -0
  58. aptdata/telemetry/instrumentation.py +164 -0
  59. aptdata/tui/__init__.py +5 -0
  60. aptdata/tui/monitor.py +279 -0
  61. aptdata-0.0.2.dist-info/METADATA +330 -0
  62. aptdata-0.0.2.dist-info/RECORD +65 -0
  63. aptdata-0.0.2.dist-info/WHEEL +4 -0
  64. aptdata-0.0.2.dist-info/entry_points.txt +3 -0
  65. aptdata-0.0.2.dist-info/licenses/LICENSE +21 -0
aptdata/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ """aptdata: A framework for smart data pipelines."""
2
+
3
+ __version__ = "0.0.2"
@@ -0,0 +1,5 @@
1
+ """Static CLI entry-point for aptdata (Typer-based)."""
2
+
3
+ from aptdata.cli.app import app
4
+
5
+ __all__ = ["app"]
aptdata/cli/app.py ADDED
@@ -0,0 +1,247 @@
1
+ """Typer-based static CLI for aptdata.
2
+
3
+ Design goals
4
+ ------------
5
+ * Machine / AI-readable: every outcome is emitted as a single JSON line on
6
+ stdout (success) or stderr (error).
7
+ * Exit codes: 0 = success, 1 = error.
8
+ * Self-documenting: Typer generates --help automatically from the docstrings
9
+ and type annotations.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import json
15
+ import sys
16
+ import time
17
+ from pathlib import Path
18
+
19
+ import typer
20
+ from opentelemetry import trace
21
+
22
+ from aptdata.cli.scaffold import scaffold
23
+ from aptdata.config.schema import write_domain_schema
24
+
25
+ app = typer.Typer(
26
+ name="aptdata",
27
+ help="Smart Data – declarative data-pipeline framework.",
28
+ add_completion=False,
29
+ )
30
+ schema_app = typer.Typer(help="Schema utilities for declarative configuration.")
31
+
32
+
33
+ def _emit(payload: dict, *, error: bool = False) -> None:
34
+ """Emit *payload* as a single JSON line to stdout or stderr."""
35
+ event = dict(payload)
36
+ span_context = trace.get_current_span().get_span_context()
37
+ event["trace_id"] = (
38
+ f"{span_context.trace_id:032x}" if span_context.is_valid else None
39
+ )
40
+ line = json.dumps(event, default=str)
41
+ if error:
42
+ print(line, file=sys.stderr, flush=True)
43
+ else:
44
+ print(line, flush=True)
45
+
46
+
47
+ @app.command()
48
+ def run(
49
+ pipeline: str = typer.Argument(..., help="Pipeline name / identifier to run."),
50
+ env: str = typer.Option("dev", "--env", "-e", help="Target execution environment."),
51
+ dry_run: bool = typer.Option(
52
+ False,
53
+ "--dry-run",
54
+ help="Validate and compile the pipeline without executing it.",
55
+ ),
56
+ ) -> None:
57
+ """Run a registered data pipeline.
58
+
59
+ Emits structured JSON logs and returns exit code 0 on success or 1 on
60
+ failure so that orchestrators and AI agents can parse the outcome.
61
+
62
+ Examples
63
+ --------
64
+ aptdata run pipeline_x --env prod
65
+ aptdata run pipeline_x --env staging --dry-run
66
+ """
67
+ started_at = time.time()
68
+ _emit(
69
+ {
70
+ "event": "pipeline.started",
71
+ "pipeline": pipeline,
72
+ "env": env,
73
+ "dry_run": dry_run,
74
+ }
75
+ )
76
+
77
+ try:
78
+ # Plugin registry look-up (stub – real implementations are in plugins/)
79
+ from aptdata.plugins import registry # noqa: PLC0415
80
+
81
+ pipeline_cls = registry.get(pipeline)
82
+ if pipeline_cls is None:
83
+ raise LookupError(f"Pipeline '{pipeline}' not found in registry.")
84
+
85
+ instance = pipeline_cls(system_id=pipeline)
86
+
87
+ if not dry_run:
88
+ instance.run()
89
+
90
+ elapsed = round(time.time() - started_at, 3)
91
+ _emit(
92
+ {
93
+ "event": "pipeline.completed",
94
+ "pipeline": pipeline,
95
+ "env": env,
96
+ "dry_run": dry_run,
97
+ "elapsed_seconds": elapsed,
98
+ }
99
+ )
100
+ raise SystemExit(0)
101
+
102
+ except LookupError as exc:
103
+ elapsed = round(time.time() - started_at, 3)
104
+ _emit(
105
+ {
106
+ "event": "pipeline.error",
107
+ "pipeline": pipeline,
108
+ "env": env,
109
+ "error": str(exc),
110
+ "elapsed_seconds": elapsed,
111
+ },
112
+ error=True,
113
+ )
114
+ raise SystemExit(1) from exc
115
+
116
+ except Exception as exc: # noqa: BLE001
117
+ elapsed = round(time.time() - started_at, 3)
118
+ _emit(
119
+ {
120
+ "event": "pipeline.error",
121
+ "pipeline": pipeline,
122
+ "env": env,
123
+ "error": str(exc),
124
+ "elapsed_seconds": elapsed,
125
+ },
126
+ error=True,
127
+ )
128
+ raise SystemExit(1) from exc
129
+
130
+
131
+ @app.command()
132
+ def monitor(
133
+ refresh: float = typer.Option(
134
+ 1.0,
135
+ "--refresh",
136
+ "-r",
137
+ help="Dashboard refresh interval in seconds.",
138
+ ),
139
+ ) -> None:
140
+ """Open the interactive TUI monitoring dashboard.
141
+
142
+ Displays the pipeline DAG, memory usage and task status in real time.
143
+ Press **q** or **Ctrl+C** to exit.
144
+
145
+ Examples
146
+ --------
147
+ aptdata monitor
148
+ aptdata monitor --refresh 0.5
149
+ """
150
+ from aptdata.tui.monitor import MonitorApp # noqa: PLC0415
151
+
152
+ app_instance = MonitorApp(refresh_interval=refresh)
153
+ app_instance.run()
154
+
155
+
156
+ @app.command()
157
+ def mcp_start(
158
+ transport: str = typer.Option(
159
+ "stdio",
160
+ "--transport",
161
+ "-t",
162
+ help="MCP transport to use (stdio or sse).",
163
+ ),
164
+ ) -> None:
165
+ """Start the MCP (Model Context Protocol) server.
166
+
167
+ This exposes aptdata tools and resources so that AI agents
168
+ (Claude Desktop, Copilot, Devin, …) can discover and run pipelines.
169
+
170
+ Examples
171
+ --------
172
+ aptdata mcp-start
173
+ aptdata mcp-start --transport sse
174
+ """
175
+ _emit({"event": "mcp.server.starting", "transport": transport})
176
+ try:
177
+ from aptdata.mcp.server import mcp as mcp_server # noqa: PLC0415
178
+
179
+ mcp_server.run(transport=transport)
180
+ except Exception as exc: # noqa: BLE001
181
+ _emit(
182
+ {"event": "mcp.server.error", "error": str(exc)},
183
+ error=True,
184
+ )
185
+ raise SystemExit(1) from exc
186
+
187
+
188
+ app.command()(scaffold)
189
+ app.add_typer(schema_app, name="schema")
190
+
191
+ from aptdata.cli.commands import ( # noqa: E402
192
+ config_app,
193
+ mesh_app,
194
+ plugin_app,
195
+ system_app,
196
+ telemetry_app,
197
+ )
198
+ from aptdata.cli.interactive import interactive_command # noqa: E402
199
+
200
+ app.add_typer(system_app, name="system")
201
+ app.add_typer(plugin_app, name="plugin")
202
+ app.add_typer(config_app, name="config")
203
+ app.add_typer(telemetry_app, name="telemetry")
204
+ app.add_typer(mesh_app, name="mesh")
205
+
206
+
207
+ @app.command("interactive")
208
+ def interactive() -> None:
209
+ """Launch the interactive wizard mode."""
210
+ interactive_command()
211
+
212
+
213
+ @schema_app.command("export")
214
+ def schema_export(
215
+ output: Path = typer.Option(
216
+ ...,
217
+ "--output",
218
+ "-o",
219
+ help="Output path for the generated JSON Schema.",
220
+ ),
221
+ ) -> None:
222
+ """Export JSON Schema for declarative YAML configs."""
223
+ started_at = time.time()
224
+ _emit({"event": "schema.export.started", "output": str(output)})
225
+ try:
226
+ write_domain_schema(output)
227
+ elapsed = round(time.time() - started_at, 3)
228
+ _emit(
229
+ {
230
+ "event": "schema.export.completed",
231
+ "output": str(output),
232
+ "elapsed_seconds": elapsed,
233
+ }
234
+ )
235
+ raise SystemExit(0)
236
+ except Exception as exc: # noqa: BLE001
237
+ elapsed = round(time.time() - started_at, 3)
238
+ _emit(
239
+ {
240
+ "event": "schema.export.error",
241
+ "output": str(output),
242
+ "error": str(exc),
243
+ "elapsed_seconds": elapsed,
244
+ },
245
+ error=True,
246
+ )
247
+ raise SystemExit(1) from exc
@@ -0,0 +1,9 @@
1
+ """CLI sub-command packages for aptdata."""
2
+
3
+ from aptdata.cli.commands.config_cmd import config_app
4
+ from aptdata.cli.commands.mesh_cmd import mesh_app
5
+ from aptdata.cli.commands.plugin_cmd import plugin_app
6
+ from aptdata.cli.commands.system_cmd import system_app
7
+ from aptdata.cli.commands.telemetry_cmd import telemetry_app
8
+
9
+ __all__ = ["system_app", "plugin_app", "config_app", "telemetry_app", "mesh_app"]
@@ -0,0 +1,128 @@
1
+ """CLI sub-commands for YAML configuration management."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+ import typer
8
+
9
+ from aptdata.cli.rendering.console import SmartConsole
10
+ from aptdata.cli.rendering.panels import yaml_preview
11
+ from aptdata.cli.rendering.tables import config_summary_table
12
+
13
+ config_app = typer.Typer(name="config", help="Manage declarative YAML configurations.")
14
+
15
+ _STARTER_YAML = """\
16
+ # aptdata declarative pipeline configuration
17
+ metadata:
18
+ name: my_pipeline
19
+ version: "1.0"
20
+ description: A sample pipeline
21
+
22
+ system:
23
+ system_id: my_pipeline
24
+ flows:
25
+ - flow_id: main_flow
26
+ components:
27
+ - component_id: extract
28
+ metadata:
29
+ kind: EXTRACT
30
+ description: Extract raw data
31
+ - component_id: transform
32
+ metadata:
33
+ kind: TRANSFORM
34
+ description: Transform data
35
+ - component_id: load
36
+ metadata:
37
+ kind: LOAD
38
+ description: Load to destination
39
+ edges:
40
+ - source_id: extract
41
+ target_id: transform
42
+ - source_id: transform
43
+ target_id: load
44
+ """
45
+
46
+
47
+ @config_app.command("validate")
48
+ def config_validate(
49
+ path: Path = typer.Argument(..., help="Path to YAML config file.", exists=True),
50
+ ) -> None:
51
+ """Parse and validate a YAML config file."""
52
+ from aptdata.config.parser import YamlConfigParser # noqa: PLC0415
53
+
54
+ console = SmartConsole(json_mode=False)
55
+
56
+ try:
57
+ with console.spinner(f"Validating '{path}'..."):
58
+ parser = YamlConfigParser()
59
+ parsed = parser.parse_file(path)
60
+ console.success(f"Config valid: system_id='{parsed.system.system_id}'")
61
+ except Exception as exc: # noqa: BLE001
62
+ console.error(f"Validation failed: {exc}")
63
+ raise typer.Exit(1) from exc
64
+
65
+
66
+ @config_app.command("init")
67
+ def config_init(
68
+ output: Path = typer.Option(
69
+ Path("pipeline.yaml"),
70
+ "--output",
71
+ "-o",
72
+ help="Output file path.",
73
+ ),
74
+ template: bool = typer.Option(
75
+ False, "--template", help="Use the starter template."
76
+ ),
77
+ ) -> None:
78
+ """Generate a starter YAML configuration file."""
79
+ console = SmartConsole(json_mode=False)
80
+
81
+ if output.exists():
82
+ console.error(f"File '{output}' already exists.")
83
+ raise typer.Exit(1)
84
+
85
+ output.write_text(_STARTER_YAML, encoding="utf-8")
86
+ console.success(f"Config template written to '{output}'.")
87
+ console.render(yaml_preview(_STARTER_YAML))
88
+
89
+
90
+ @config_app.command("show")
91
+ def config_show(
92
+ path: Path = typer.Argument(..., help="Path to YAML config file.", exists=True),
93
+ ) -> None:
94
+ """Pretty-print a YAML config file with syntax highlighting."""
95
+ console = SmartConsole(json_mode=False)
96
+ content = path.read_text(encoding="utf-8")
97
+ console.render(yaml_preview(content))
98
+
99
+
100
+ @config_app.command("run")
101
+ def config_run(
102
+ path: Path = typer.Argument(..., help="Path to YAML config file.", exists=True),
103
+ env: str = typer.Option("dev", "--env", "-e", help="Target environment."),
104
+ ) -> None:
105
+ """Parse a YAML config, register the system, and execute it."""
106
+ from aptdata.config.parser import YamlConfigParser # noqa: PLC0415
107
+ from aptdata.plugins import registry # noqa: PLC0415
108
+
109
+ console = SmartConsole(json_mode=False)
110
+
111
+ try:
112
+ with console.spinner(f"Parsing '{path}'..."):
113
+ parser = YamlConfigParser()
114
+ parsed = parser.parse_file(path)
115
+
116
+ system_id = parsed.system.system_id
117
+ system_cls = type(parsed.system)
118
+ registry.register(system_id, system_cls)
119
+
120
+ console.render(config_summary_table(parsed))
121
+
122
+ with console.spinner(f"Running '{system_id}' [{env}]..."):
123
+ parsed.system.run()
124
+
125
+ console.success(f"System '{system_id}' executed successfully.")
126
+ except Exception as exc: # noqa: BLE001
127
+ console.error(f"Execution failed: {exc}")
128
+ raise typer.Exit(1) from exc