interloper-toolkit 0.65.1__tar.gz → 0.67.0__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.
- {interloper_toolkit-0.65.1 → interloper_toolkit-0.67.0}/PKG-INFO +1 -1
- {interloper_toolkit-0.65.1 → interloper_toolkit-0.67.0}/pyproject.toml +1 -1
- {interloper_toolkit-0.65.1 → interloper_toolkit-0.67.0}/pyproject.toml.orig +1 -1
- {interloper_toolkit-0.65.1 → interloper_toolkit-0.67.0}/src/interloper_toolkit/analytics.py +4 -4
- {interloper_toolkit-0.65.1 → interloper_toolkit-0.67.0}/src/interloper_toolkit/catalog.py +3 -3
- {interloper_toolkit-0.65.1 → interloper_toolkit-0.67.0}/src/interloper_toolkit/collection.py +2 -2
- {interloper_toolkit-0.65.1 → interloper_toolkit-0.67.0}/src/interloper_toolkit/lineage.py +8 -8
- {interloper_toolkit-0.65.1 → interloper_toolkit-0.67.0}/src/interloper_toolkit/scheduling.py +11 -11
- {interloper_toolkit-0.65.1 → interloper_toolkit-0.67.0}/README.md +0 -0
- {interloper_toolkit-0.65.1 → interloper_toolkit-0.67.0}/src/interloper_toolkit/__init__.py +0 -0
- {interloper_toolkit-0.65.1 → interloper_toolkit-0.67.0}/src/interloper_toolkit/context.py +0 -0
- {interloper_toolkit-0.65.1 → interloper_toolkit-0.67.0}/src/interloper_toolkit/models.py +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# ###############
|
|
4
4
|
[project]
|
|
5
5
|
name = "interloper-toolkit"
|
|
6
|
-
version = "0.
|
|
6
|
+
version = "0.67.0"
|
|
7
7
|
description = "Interloper shared read-only tool functions for AI surfaces (agent, MCP)"
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
authors = [{ name = "Guillaume Onfroy", email = "guillaume@digitlcloud.com" }]
|
|
@@ -32,7 +32,7 @@ def run_history_summary(
|
|
|
32
32
|
success rate, and average duration.
|
|
33
33
|
"""
|
|
34
34
|
try:
|
|
35
|
-
runs = ctx.store.
|
|
35
|
+
runs = ctx.store.runs.list_all(
|
|
36
36
|
ctx.org_id,
|
|
37
37
|
component_id=UUID(component_id) if component_id else None,
|
|
38
38
|
limit=500,
|
|
@@ -79,7 +79,7 @@ def partition_coverage(
|
|
|
79
79
|
"""
|
|
80
80
|
try:
|
|
81
81
|
jid = UUID(component_id)
|
|
82
|
-
runs = ctx.store.
|
|
82
|
+
runs = ctx.store.runs.list_all(ctx.org_id, component_id=jid, limit=1000)
|
|
83
83
|
|
|
84
84
|
start = datetime.date.fromisoformat(start_date)
|
|
85
85
|
end = datetime.date.fromisoformat(end_date)
|
|
@@ -131,7 +131,7 @@ def freshness_check(ctx: ToolkitContext) -> FreshnessReport | ToolError:
|
|
|
131
131
|
any that haven't succeeded in over 24 hours.
|
|
132
132
|
"""
|
|
133
133
|
try:
|
|
134
|
-
jobs = ctx.store.
|
|
134
|
+
jobs = ctx.store.components.list_all(ctx.org_id, kinds=["job"])
|
|
135
135
|
now = datetime.datetime.now(tz=datetime.timezone.utc)
|
|
136
136
|
|
|
137
137
|
results = []
|
|
@@ -139,7 +139,7 @@ def freshness_check(ctx: ToolkitContext) -> FreshnessReport | ToolError:
|
|
|
139
139
|
if not (job.config or {}).get("enabled", True):
|
|
140
140
|
continue
|
|
141
141
|
component_id = job.id
|
|
142
|
-
runs = ctx.store.
|
|
142
|
+
runs = ctx.store.runs.list_all(ctx.org_id, component_id=component_id, status="success", limit=1)
|
|
143
143
|
last_success = runs[0] if runs else None
|
|
144
144
|
|
|
145
145
|
hours_since = None
|
|
@@ -9,7 +9,7 @@ from __future__ import annotations
|
|
|
9
9
|
|
|
10
10
|
from typing import Any
|
|
11
11
|
|
|
12
|
-
from interloper.oauth import
|
|
12
|
+
from interloper.oauth import OAuthAppCredentials
|
|
13
13
|
|
|
14
14
|
from interloper_toolkit.context import ToolkitContext
|
|
15
15
|
from interloper_toolkit.models import (
|
|
@@ -86,7 +86,7 @@ def list_definitions(
|
|
|
86
86
|
|
|
87
87
|
collection_counts: dict[str, int] = {}
|
|
88
88
|
if kind == "source":
|
|
89
|
-
for s in ctx.store.
|
|
89
|
+
for s in ctx.store.components.list_all(ctx.org_id, kinds=["source"]):
|
|
90
90
|
collection_counts[s.key] = collection_counts.get(s.key, 0) + 1
|
|
91
91
|
|
|
92
92
|
results = []
|
|
@@ -111,7 +111,7 @@ def list_definitions(
|
|
|
111
111
|
entry.provider = defn.get("provider")
|
|
112
112
|
entry.required_fields = schema.get("required", [])
|
|
113
113
|
entry.oauth = oauth is not None
|
|
114
|
-
entry.oauth_available =
|
|
114
|
+
entry.oauth_available = OAuthAppCredentials.is_configured(oauth["provider"]) if oauth else False
|
|
115
115
|
results.append(entry)
|
|
116
116
|
|
|
117
117
|
return DefinitionList(kind=kind, count=len(results), definitions=results)
|
{interloper_toolkit-0.65.1 → interloper_toolkit-0.67.0}/src/interloper_toolkit/collection.py
RENAMED
|
@@ -30,7 +30,7 @@ def list_components(
|
|
|
30
30
|
try:
|
|
31
31
|
if kind is None:
|
|
32
32
|
counts: dict[str, int] = {}
|
|
33
|
-
for c in ctx.store.
|
|
33
|
+
for c in ctx.store.components.list_all(ctx.org_id):
|
|
34
34
|
counts[c.kind] = counts.get(c.kind, 0) + 1
|
|
35
35
|
return ComponentCounts(
|
|
36
36
|
component_counts=counts,
|
|
@@ -40,7 +40,7 @@ def list_components(
|
|
|
40
40
|
return ToolError(error=f"Unknown kind '{kind}'", valid_kinds=sorted(KINDS.keys()))
|
|
41
41
|
|
|
42
42
|
results = []
|
|
43
|
-
for c in ctx.store.
|
|
43
|
+
for c in ctx.store.components.list_all(ctx.org_id, kinds=[kind]):
|
|
44
44
|
entry = ComponentSummary(
|
|
45
45
|
id=str(c.id),
|
|
46
46
|
key=c.key,
|
|
@@ -30,13 +30,13 @@ def get_upstream(ctx: ToolkitContext, asset_id: str) -> UpstreamResult | ToolErr
|
|
|
30
30
|
including the parameter name used for each dependency.
|
|
31
31
|
"""
|
|
32
32
|
try:
|
|
33
|
-
deps = ctx.store.
|
|
33
|
+
deps = ctx.store.relations.list_all(ctx.org_id, type="dependency")
|
|
34
34
|
target = UUID(asset_id)
|
|
35
35
|
|
|
36
36
|
upstream = []
|
|
37
37
|
for dep in deps:
|
|
38
38
|
if dep.src_id == target:
|
|
39
|
-
asset = ctx.store.
|
|
39
|
+
asset = ctx.store.components.get(dep.dst_id, kind="asset")
|
|
40
40
|
upstream.append(DependencyEdge(
|
|
41
41
|
asset_id=str(dep.dst_id),
|
|
42
42
|
param_name=dep.slot,
|
|
@@ -58,13 +58,13 @@ def get_downstream(ctx: ToolkitContext, asset_id: str) -> DownstreamResult | Too
|
|
|
58
58
|
Returns the list of assets that directly depend on this asset.
|
|
59
59
|
"""
|
|
60
60
|
try:
|
|
61
|
-
deps = ctx.store.
|
|
61
|
+
deps = ctx.store.relations.list_all(ctx.org_id, type="dependency")
|
|
62
62
|
target = UUID(asset_id)
|
|
63
63
|
|
|
64
64
|
downstream = []
|
|
65
65
|
for dep in deps:
|
|
66
66
|
if dep.dst_id == target:
|
|
67
|
-
asset = ctx.store.
|
|
67
|
+
asset = ctx.store.components.get(dep.src_id, kind="asset")
|
|
68
68
|
downstream.append(DependencyEdge(
|
|
69
69
|
asset_id=str(dep.src_id),
|
|
70
70
|
param_name=dep.slot,
|
|
@@ -165,8 +165,8 @@ def cross_source_dependencies(ctx: ToolkitContext) -> CrossSourceDependencies |
|
|
|
165
165
|
different sources.
|
|
166
166
|
"""
|
|
167
167
|
try:
|
|
168
|
-
deps = ctx.store.
|
|
169
|
-
assets = ctx.store.
|
|
168
|
+
deps = ctx.store.relations.list_all(ctx.org_id, type="dependency")
|
|
169
|
+
assets = ctx.store.components.list_all(ctx.org_id, kinds=["asset"])
|
|
170
170
|
|
|
171
171
|
asset_source: dict[UUID, UUID | None] = {}
|
|
172
172
|
asset_info: dict[UUID, AssetRef] = {}
|
|
@@ -211,8 +211,8 @@ def _build_adjacency(
|
|
|
211
211
|
``(adjacency_map, asset_info_map)`` — info values feed
|
|
212
212
|
:class:`LineageItem` kwargs (asset_key, source_id, source_key).
|
|
213
213
|
"""
|
|
214
|
-
deps = ctx.store.
|
|
215
|
-
assets = ctx.store.
|
|
214
|
+
deps = ctx.store.relations.list_all(ctx.org_id, type="dependency")
|
|
215
|
+
assets = ctx.store.components.list_all(ctx.org_id, kinds=["asset"])
|
|
216
216
|
|
|
217
217
|
asset_info: dict[UUID, dict[str, str]] = {}
|
|
218
218
|
source_keys: dict[UUID, str] = {}
|
{interloper_toolkit-0.65.1 → interloper_toolkit-0.67.0}/src/interloper_toolkit/scheduling.py
RENAMED
|
@@ -32,7 +32,7 @@ def list_jobs(ctx: ToolkitContext) -> JobList | ToolError:
|
|
|
32
32
|
last_run_at, and next_run_at.
|
|
33
33
|
"""
|
|
34
34
|
try:
|
|
35
|
-
jobs = ctx.store.
|
|
35
|
+
jobs = ctx.store.components.list_all(ctx.org_id, kinds=["job"])
|
|
36
36
|
return JobList(count=len(jobs), jobs=jobs)
|
|
37
37
|
except Exception as e:
|
|
38
38
|
return ToolError(error=str(e))
|
|
@@ -48,8 +48,8 @@ def get_job_health(ctx: ToolkitContext, component_id: str) -> JobHealth | ToolEr
|
|
|
48
48
|
"""
|
|
49
49
|
try:
|
|
50
50
|
jid = UUID(component_id)
|
|
51
|
-
job = ctx.store.
|
|
52
|
-
runs = ctx.store.
|
|
51
|
+
job = ctx.store.components.get(jid, kind="job")
|
|
52
|
+
runs = ctx.store.runs.list_all(ctx.org_id, component_id=jid, limit=20)
|
|
53
53
|
|
|
54
54
|
total = len(runs)
|
|
55
55
|
success = sum(1 for r in runs if r.status == "success")
|
|
@@ -94,7 +94,7 @@ def list_recent_runs(
|
|
|
94
94
|
limit: Maximum number of runs to return (default 20).
|
|
95
95
|
"""
|
|
96
96
|
try:
|
|
97
|
-
runs = ctx.store.
|
|
97
|
+
runs = ctx.store.runs.list_all(
|
|
98
98
|
ctx.org_id,
|
|
99
99
|
component_id=UUID(component_id) if component_id else None,
|
|
100
100
|
status=status,
|
|
@@ -115,9 +115,9 @@ def get_run_detail(ctx: ToolkitContext, run_id: str) -> RunDetail | ToolError:
|
|
|
115
115
|
"""
|
|
116
116
|
try:
|
|
117
117
|
rid = UUID(run_id)
|
|
118
|
-
run = ctx.store.
|
|
119
|
-
events = ctx.store.
|
|
120
|
-
asset_execs = ctx.store.list_asset_executions(rid)
|
|
118
|
+
run = ctx.store.runs.get(rid)
|
|
119
|
+
events = ctx.store.events.list_all(run_id=rid)
|
|
120
|
+
asset_execs = ctx.store.events.list_asset_executions(rid)
|
|
121
121
|
|
|
122
122
|
return RunDetail(run=run, events=events, asset_executions=asset_execs)
|
|
123
123
|
except Exception as e:
|
|
@@ -133,12 +133,12 @@ def list_failures(ctx: ToolkitContext, limit: int = 20) -> FailureList | ToolErr
|
|
|
133
133
|
Returns failed runs along with the error messages from their events.
|
|
134
134
|
"""
|
|
135
135
|
try:
|
|
136
|
-
failed_runs = ctx.store.
|
|
136
|
+
failed_runs = ctx.store.runs.list_all(ctx.org_id, status="failed", limit=limit)
|
|
137
137
|
|
|
138
138
|
results = []
|
|
139
139
|
for run in failed_runs:
|
|
140
140
|
run_id = run.id
|
|
141
|
-
events = ctx.store.
|
|
141
|
+
events = ctx.store.events.list_all(run_id=run_id)
|
|
142
142
|
errors = [
|
|
143
143
|
RunErrorEvent(component_key=e.component_key, error=e.error, timestamp=e.timestamp)
|
|
144
144
|
for e in events
|
|
@@ -164,9 +164,9 @@ def list_backfills(ctx: ToolkitContext, active_only: bool = True) -> BackfillLis
|
|
|
164
164
|
"""
|
|
165
165
|
try:
|
|
166
166
|
if active_only:
|
|
167
|
-
backfills = ctx.store.list_active_backfills(ctx.org_id)
|
|
167
|
+
backfills = ctx.store.runs.list_active_backfills(ctx.org_id)
|
|
168
168
|
else:
|
|
169
|
-
backfills = ctx.store.list_backfills(ctx.org_id)
|
|
169
|
+
backfills = ctx.store.runs.list_backfills(ctx.org_id)
|
|
170
170
|
return BackfillList(count=len(backfills), backfills=backfills)
|
|
171
171
|
except Exception as e:
|
|
172
172
|
return ToolError(error=str(e))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|