recce-nightly 1.15.0.20250806__py3-none-any.whl → 1.26.0.20251124__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.
Potentially problematic release.
This version of recce-nightly might be problematic. Click here for more details.
- recce/VERSION +1 -1
- recce/__init__.py +5 -0
- recce/adapter/dbt_adapter/__init__.py +12 -3
- recce/artifact.py +74 -1
- recce/cli.py +642 -101
- recce/config.py +2 -2
- recce/connect_to_cloud.py +1 -1
- recce/core.py +2 -2
- recce/data/404.html +1 -1
- recce/data/__next.__PAGE__.txt +10 -0
- recce/data/__next._full.txt +23 -0
- recce/data/__next._head.txt +8 -0
- recce/data/__next._index.txt +8 -0
- recce/data/__next._tree.txt +5 -0
- recce/data/_next/static/52aV_JrNUZU6dMFgvTQEO/_buildManifest.js +11 -0
- recce/data/_next/static/52aV_JrNUZU6dMFgvTQEO/_clientMiddlewareManifest.json +1 -0
- recce/data/_next/static/chunks/02b996c7f6a29a06.js +4 -0
- recce/data/_next/static/chunks/19c10d219a6a21ff.js +1 -0
- recce/data/_next/static/chunks/2df9ec28a061971d.js +11 -0
- recce/data/_next/static/chunks/3098c987393bda15.js +1 -0
- recce/data/_next/static/chunks/393dc43e483f717a.css +2 -0
- recce/data/_next/static/chunks/399e8d91a7e45073.js +2 -0
- recce/data/_next/static/chunks/4d0186f631230245.js +1 -0
- recce/data/_next/static/chunks/5794ba9e10a9c060.js +11 -0
- recce/data/_next/static/chunks/715761c929a3f28b.js +110 -0
- recce/data/_next/static/chunks/71f88fcc615bf282.js +1 -0
- recce/data/_next/static/chunks/80d2a95eaf1201ea.js +1 -0
- recce/data/_next/static/chunks/9979c6109bbbee35.js +1 -0
- recce/data/_next/static/chunks/99d638224186c118.js +1 -0
- recce/data/_next/static/chunks/d003eb36240e92f3.js +1 -0
- recce/data/_next/static/chunks/d3167cdfec4fc351.js +1 -0
- recce/data/_next/static/chunks/e124bccf574a3361.css +1 -0
- recce/data/_next/static/chunks/f40141db1bdb46f0.css +6 -0
- recce/data/_next/static/chunks/fcc53a88741a52f9.js +1 -0
- recce/data/_next/static/chunks/turbopack-b1920d28cfb1f28d.js +3 -0
- recce/data/_next/static/media/favicon.a8d38d84.ico +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-800-normal.d80d830d.woff2 +0 -0
- recce/data/_next/static/media/{montserrat-cyrillic-800-normal.bd5c9f50.woff → montserrat-cyrillic-800-normal.f9d58125.woff} +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.076c2a93.woff2 +0 -0
- recce/data/_next/static/media/montserrat-latin-800-normal.cde454cc.woff2 +0 -0
- recce/data/_next/static/media/{montserrat-latin-800-normal.fc315020.woff → montserrat-latin-800-normal.d5761935.woff} +0 -0
- recce/data/_next/static/media/montserrat-latin-ext-800-normal.40ec0659.woff2 +0 -0
- recce/data/_next/static/media/{montserrat-latin-ext-800-normal.2e5381b2.woff → montserrat-latin-ext-800-normal.b671449b.woff} +0 -0
- recce/data/_next/static/media/{montserrat-vietnamese-800-normal.20c545e6.woff → montserrat-vietnamese-800-normal.9f7b8541.woff} +0 -0
- recce/data/_next/static/media/montserrat-vietnamese-800-normal.f9eb854e.woff2 +0 -0
- recce/data/_not-found/__next._full.txt +17 -0
- recce/data/_not-found/__next._head.txt +8 -0
- recce/data/_not-found/__next._index.txt +8 -0
- recce/data/_not-found/__next._not-found.__PAGE__.txt +5 -0
- recce/data/_not-found/__next._not-found.txt +4 -0
- recce/data/_not-found/__next._tree.txt +3 -0
- recce/data/_not-found.html +1 -0
- recce/data/_not-found.txt +17 -0
- recce/data/index.html +1 -1
- recce/data/index.txt +21 -23
- recce/event/__init__.py +9 -8
- recce/event/collector.py +3 -1
- recce/event/track.py +10 -0
- recce/github.py +1 -1
- recce/mcp_server.py +716 -0
- recce/models/types.py +35 -2
- recce/pull_request.py +1 -1
- recce/run.py +2 -2
- recce/server.py +105 -3
- recce/state/__init__.py +31 -0
- recce/state/cloud.py +632 -0
- recce/state/const.py +26 -0
- recce/state/local.py +56 -0
- recce/state/state.py +119 -0
- recce/state/state_loader.py +174 -0
- recce/summary.py +21 -1
- recce/tasks/dataframe.py +63 -1
- recce/tasks/rowcount.py +4 -1
- recce/tasks/schema.py +4 -1
- recce/util/api_token.py +9 -2
- recce/util/breaking.py +1 -1
- recce/util/io.py +2 -2
- recce/util/lineage.py +14 -18
- recce/util/recce_cloud.py +187 -7
- recce/yaml/__init__.py +2 -2
- recce_cloud/__init__.py +24 -0
- recce_cloud/api/__init__.py +17 -0
- recce_cloud/api/base.py +111 -0
- recce_cloud/api/client.py +150 -0
- recce_cloud/api/exceptions.py +26 -0
- recce_cloud/api/factory.py +63 -0
- recce_cloud/api/github.py +76 -0
- recce_cloud/api/gitlab.py +82 -0
- recce_cloud/artifact.py +57 -0
- recce_cloud/ci_providers/__init__.py +9 -0
- recce_cloud/ci_providers/base.py +82 -0
- recce_cloud/ci_providers/detector.py +147 -0
- recce_cloud/ci_providers/github_actions.py +136 -0
- recce_cloud/ci_providers/gitlab_ci.py +130 -0
- recce_cloud/cli.py +245 -0
- recce_cloud/upload.py +214 -0
- {recce_nightly-1.15.0.20250806.dist-info → recce_nightly-1.26.0.20251124.dist-info}/METADATA +54 -28
- recce_nightly-1.26.0.20251124.dist-info/RECORD +180 -0
- {recce_nightly-1.15.0.20250806.dist-info → recce_nightly-1.26.0.20251124.dist-info}/top_level.txt +1 -0
- tests/adapter/dbt_adapter/test_dbt_cll.py +4 -2
- tests/recce_cloud/__init__.py +0 -0
- tests/recce_cloud/test_ci_providers.py +351 -0
- tests/recce_cloud/test_cli.py +372 -0
- tests/recce_cloud/test_client.py +273 -0
- tests/recce_cloud/test_platform_clients.py +333 -0
- tests/test_cli.py +106 -3
- tests/test_cli_mcp_optional.py +45 -0
- tests/test_cloud_listing_cli.py +324 -0
- tests/test_core.py +147 -0
- tests/test_mcp_server.py +332 -0
- tests/test_server.py +6 -6
- tests/test_summary.py +14 -6
- recce/data/_next/static/Q_5ThPsmamd4VAGXuqwgi/_buildManifest.js +0 -1
- recce/data/_next/static/chunks/0376eeba-3db2196398d62270.js +0 -1
- recce/data/_next/static/chunks/068b80ea-833a129468ee1622.js +0 -1
- recce/data/_next/static/chunks/0ddaf06c-c7961285f66460f6.js +0 -1
- recce/data/_next/static/chunks/1268aea1-6dc1251c01bd724b.js +0 -54
- recce/data/_next/static/chunks/12f8fac4-16838e42d28d45c3.js +0 -1
- recce/data/_next/static/chunks/235b8375-8c84c51d7bd4f6aa.js +0 -1
- recce/data/_next/static/chunks/2541941f-2cd3a7c2d629bd33.js +0 -1
- recce/data/_next/static/chunks/273-f3fa401bd2b6fc91.js +0 -10
- recce/data/_next/static/chunks/2fc37c1e-910deebeb3d77c90.js +0 -1
- recce/data/_next/static/chunks/338-2e7eed5135c64550.js +0 -30
- recce/data/_next/static/chunks/367-ab8b16dd5f8586ca.js +0 -1
- recce/data/_next/static/chunks/3a92ee20-0400ffe460c7c803.js +0 -1
- recce/data/_next/static/chunks/62446465-423c03bb8c1f59b6.js +0 -1
- recce/data/_next/static/chunks/6af7f9e9-60aa8706f49dae45.js +0 -1
- recce/data/_next/static/chunks/6cf54382-49d52ae6e564e2ac.js +0 -1
- recce/data/_next/static/chunks/6dc81886-78e2efe4538794ae.js +0 -1
- recce/data/_next/static/chunks/715e4acc-9e2e6df4eb3809d1.js +0 -1
- recce/data/_next/static/chunks/72-181b430654230f0e.js +0 -1
- recce/data/_next/static/chunks/786-774e3e3ed70a41b3.js +0 -1
- recce/data/_next/static/chunks/8d700b6a.7fe2c8c3f4e333a6.js +0 -1
- recce/data/_next/static/chunks/a69d64b4-d6890125a87b0aba.js +0 -1
- recce/data/_next/static/chunks/ae307f12-01100009689ace61.js +0 -1
- recce/data/_next/static/chunks/app/_not-found/page-c7ef8ed6dc07aaeb.js +0 -1
- recce/data/_next/static/chunks/app/layout-744f0a78e9e50e60.js +0 -1
- recce/data/_next/static/chunks/app/page-e8f798c2ae3f59c2.js +0 -1
- recce/data/_next/static/chunks/c0015c5c-82c219792582c104.js +0 -1
- recce/data/_next/static/chunks/d90cfbaa-e7d779b3912afeec.js +0 -1
- recce/data/_next/static/chunks/e07c302e-cd170429646873e1.js +0 -1
- recce/data/_next/static/chunks/fa5fb511-15fb438349ad5b97.js +0 -1
- recce/data/_next/static/chunks/framework-7950757d31580329.js +0 -1
- recce/data/_next/static/chunks/main-app-4df79eb11c34d43c.js +0 -1
- recce/data/_next/static/chunks/main-cd6c104af638214a.js +0 -1
- recce/data/_next/static/chunks/pages/_app-73008661edbd5e05.js +0 -1
- recce/data/_next/static/chunks/pages/_error-cf8bbdc3cf76c83f.js +0 -1
- recce/data/_next/static/chunks/webpack-84df6dd5ae3cf908.js +0 -1
- recce/data/_next/static/css/188a3a1687e2a064.css +0 -1
- recce/data/_next/static/css/8edca58d4abcf908.css +0 -14
- recce/data/_next/static/css/abdb9814a3dd18bb.css +0 -1
- recce/data/_next/static/css/c21263c1520b615b.css +0 -1
- recce/data/_next/static/media/montserrat-cyrillic-800-normal.22628180.woff2 +0 -0
- recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.94a63aea.woff2 +0 -0
- recce/data/_next/static/media/montserrat-latin-800-normal.6f8fa298.woff2 +0 -0
- recce/data/_next/static/media/montserrat-latin-ext-800-normal.013b84f9.woff2 +0 -0
- recce/data/_next/static/media/montserrat-vietnamese-800-normal.c0035377.woff2 +0 -0
- recce/state.py +0 -865
- recce_nightly-1.15.0.20250806.dist-info/RECORD +0 -156
- tests/test_state.py +0 -134
- /recce/data/_next/static/{Q_5ThPsmamd4VAGXuqwgi → 52aV_JrNUZU6dMFgvTQEO}/_ssgManifest.js +0 -0
- /recce/data/_next/static/chunks/{polyfills-42372ed130431b0a.js → a6dad97d9634a72d.js} +0 -0
- /recce/data/_next/static/media/{montserrat-cyrillic-ext-800-normal.e6e0d8d0.woff → montserrat-cyrillic-ext-800-normal.a4fa76b5.woff} +0 -0
- /recce/data/_next/static/media/{reload-image.79aabb7d.svg → reload-image.7aa931c7.svg} +0 -0
- {recce_nightly-1.15.0.20250806.dist-info → recce_nightly-1.26.0.20251124.dist-info}/WHEEL +0 -0
- {recce_nightly-1.15.0.20250806.dist-info → recce_nightly-1.26.0.20251124.dist-info}/entry_points.txt +0 -0
- {recce_nightly-1.15.0.20250806.dist-info → recce_nightly-1.26.0.20251124.dist-info}/licenses/LICENSE +0 -0
recce/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.
|
|
1
|
+
1.26.0.20251124
|
recce/__init__.py
CHANGED
|
@@ -35,6 +35,11 @@ def is_ci_env():
|
|
|
35
35
|
return False
|
|
36
36
|
|
|
37
37
|
|
|
38
|
+
def is_recce_cloud_instance():
|
|
39
|
+
"""Check if running in Recce Cloud instance."""
|
|
40
|
+
return os.environ.get("RECCE_CLOUD_INSTANCE", "false").lower() == "true"
|
|
41
|
+
|
|
42
|
+
|
|
38
43
|
def get_runner():
|
|
39
44
|
# GitHub Action
|
|
40
45
|
if os.environ.get("GITHUB_ACTIONS", "false") == "true":
|
|
@@ -408,7 +408,7 @@ class DbtAdapter(BaseAdapter):
|
|
|
408
408
|
|
|
409
409
|
if self.adapter.connections.TYPE == "databricks":
|
|
410
410
|
# reference: get_columns_in_relation (dbt/adapters/databricks/impl.py)
|
|
411
|
-
from dbt.adapters.databricks import DatabricksColumn
|
|
411
|
+
from dbt.adapters.databricks.column import DatabricksColumn
|
|
412
412
|
|
|
413
413
|
rows = columns
|
|
414
414
|
columns = []
|
|
@@ -600,7 +600,15 @@ class DbtAdapter(BaseAdapter):
|
|
|
600
600
|
return node.compiled_code
|
|
601
601
|
else:
|
|
602
602
|
from dbt.clients import jinja
|
|
603
|
-
from dbt.context.providers import
|
|
603
|
+
from dbt.context.providers import (
|
|
604
|
+
generate_runtime_macro_context,
|
|
605
|
+
generate_runtime_model_context,
|
|
606
|
+
)
|
|
607
|
+
|
|
608
|
+
# Set up macro resolver for dbt >= 1.8
|
|
609
|
+
macro_manifest = MacroManifest(manifest.macros)
|
|
610
|
+
self.adapter.set_macro_resolver(macro_manifest)
|
|
611
|
+
self.adapter.set_macro_context_generator(generate_runtime_macro_context)
|
|
604
612
|
|
|
605
613
|
jinja_ctx = generate_runtime_model_context(node, self.runtime_config, manifest)
|
|
606
614
|
jinja_ctx.update(context)
|
|
@@ -737,6 +745,7 @@ class DbtAdapter(BaseAdapter):
|
|
|
737
745
|
nodes[unique_id] = {
|
|
738
746
|
"id": source["unique_id"],
|
|
739
747
|
"name": source["name"],
|
|
748
|
+
"source_name": source["source_name"],
|
|
740
749
|
"resource_type": source["resource_type"],
|
|
741
750
|
"package_name": source["package_name"],
|
|
742
751
|
"config": source["config"],
|
|
@@ -1591,7 +1600,7 @@ class DbtAdapter(BaseAdapter):
|
|
|
1591
1600
|
if not os.path.isfile(path):
|
|
1592
1601
|
return None
|
|
1593
1602
|
|
|
1594
|
-
with open(path, "r") as f:
|
|
1603
|
+
with open(path, "r", encoding="utf-8") as f:
|
|
1595
1604
|
json_content = f.read()
|
|
1596
1605
|
return json.loads(json_content)
|
|
1597
1606
|
|
recce/artifact.py
CHANGED
|
@@ -40,7 +40,7 @@ def verify_artifacts_path(target_path: str) -> bool:
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
def parse_dbt_version(file_path: str) -> str:
|
|
43
|
-
with open(file_path, "r") as f:
|
|
43
|
+
with open(file_path, "r", encoding="utf-8") as f:
|
|
44
44
|
data = json.load(f)
|
|
45
45
|
|
|
46
46
|
dbt_version = data.get("metadata", {}).get("dbt_version", None)
|
|
@@ -80,6 +80,64 @@ def archive_artifacts(target_path: str) -> (str, str):
|
|
|
80
80
|
return artifacts_tar_gz_path, dbt_version
|
|
81
81
|
|
|
82
82
|
|
|
83
|
+
def upload_artifacts_to_session(target_path: str, session_id: str, token: str, debug: bool = False):
|
|
84
|
+
"""Upload dbt artifacts to a specific session ID in Recce Cloud."""
|
|
85
|
+
console = Console()
|
|
86
|
+
if verify_artifacts_path(target_path) is False:
|
|
87
|
+
console.print(f"[[red]Error[/red]] Invalid target path: {target_path}")
|
|
88
|
+
console.print("Please provide a valid target path containing manifest.json and catalog.json.")
|
|
89
|
+
return 1
|
|
90
|
+
|
|
91
|
+
manifest_path = os.path.join(target_path, "manifest.json")
|
|
92
|
+
catalog_path = os.path.join(target_path, "catalog.json")
|
|
93
|
+
|
|
94
|
+
# get the adapter type from the manifest file
|
|
95
|
+
with open(manifest_path, "r", encoding="utf-8") as f:
|
|
96
|
+
manifest_data = json.load(f)
|
|
97
|
+
adapter_type = manifest_data.get("metadata", {}).get("adapter_type")
|
|
98
|
+
if adapter_type is None:
|
|
99
|
+
raise Exception("Failed to parse adapter type from manifest.json")
|
|
100
|
+
|
|
101
|
+
recce_cloud = RecceCloud(token)
|
|
102
|
+
|
|
103
|
+
session = recce_cloud.get_session(session_id)
|
|
104
|
+
|
|
105
|
+
org_id = session.get("org_id")
|
|
106
|
+
if org_id is None:
|
|
107
|
+
raise Exception(f"Session ID {session_id} does not belong to any organization.")
|
|
108
|
+
|
|
109
|
+
project_id = session.get("project_id")
|
|
110
|
+
if project_id is None:
|
|
111
|
+
raise Exception(f"Session ID {session_id} does not belong to any project.")
|
|
112
|
+
|
|
113
|
+
# Get the presigned URL for uploading the artifacts using session ID
|
|
114
|
+
console.print(f'Uploading artifacts for session ID "{session_id}"')
|
|
115
|
+
presigned_urls = recce_cloud.get_upload_urls_by_session_id(org_id, project_id, session_id)
|
|
116
|
+
if debug:
|
|
117
|
+
console.rule("Debug information", style="blue")
|
|
118
|
+
console.print(f"Org ID: {org_id}")
|
|
119
|
+
console.print(f"Project ID: {project_id}")
|
|
120
|
+
console.print(f"Session ID: {session_id}")
|
|
121
|
+
console.print(f"Manifest path: {presigned_urls['manifest_url']}")
|
|
122
|
+
console.print(f"Catalog path: {presigned_urls['catalog_url']}")
|
|
123
|
+
console.print(f"Adapter type: {adapter_type}")
|
|
124
|
+
|
|
125
|
+
# Upload the compressed artifacts (no password needed for session uploads)
|
|
126
|
+
console.print(f'Uploading manifest from path "{manifest_path}"')
|
|
127
|
+
response = requests.put(presigned_urls["manifest_url"], data=open(manifest_path, "rb").read())
|
|
128
|
+
if response.status_code != 200 and response.status_code != 204:
|
|
129
|
+
raise Exception(response.text)
|
|
130
|
+
console.print(f'Uploading catalog from path "{catalog_path}"')
|
|
131
|
+
response = requests.put(presigned_urls["catalog_url"], data=open(catalog_path, "rb").read())
|
|
132
|
+
if response.status_code != 200 and response.status_code != 204:
|
|
133
|
+
raise Exception(response.text)
|
|
134
|
+
|
|
135
|
+
# Update the session metadata
|
|
136
|
+
recce_cloud.update_session(org_id, project_id, session_id, adapter_type)
|
|
137
|
+
|
|
138
|
+
return 0
|
|
139
|
+
|
|
140
|
+
|
|
83
141
|
def upload_dbt_artifacts(target_path: str, branch: str, token: str, password: str, debug: bool = False):
|
|
84
142
|
console = Console()
|
|
85
143
|
if verify_artifacts_path(target_path) is False:
|
|
@@ -191,3 +249,18 @@ def download_dbt_artifacts(
|
|
|
191
249
|
except FileNotFoundError:
|
|
192
250
|
pass
|
|
193
251
|
return 0
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def delete_dbt_artifacts(branch: str, token: str, debug: bool = False):
|
|
255
|
+
"""Delete dbt artifacts from a specific branch in Recce Cloud."""
|
|
256
|
+
console = Console()
|
|
257
|
+
repo = hosting_repo()
|
|
258
|
+
|
|
259
|
+
if debug:
|
|
260
|
+
console.rule("Debug information", style="blue")
|
|
261
|
+
console.print(f"Git Branch: {branch}")
|
|
262
|
+
console.print(f"GitHub repository: {repo}")
|
|
263
|
+
|
|
264
|
+
console.print(f'Deleting dbt artifacts from branch: "{branch}"')
|
|
265
|
+
|
|
266
|
+
RecceCloud(token).purge_artifacts(repo, branch=branch)
|