recce-nightly 1.3.0.20250507__py3-none-any.whl → 1.4.0.20250514__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 +22 -22
- recce/adapter/base.py +11 -14
- recce/adapter/dbt_adapter/__init__.py +355 -316
- recce/adapter/dbt_adapter/dbt_version.py +3 -0
- recce/adapter/sqlmesh_adapter.py +24 -35
- recce/apis/check_api.py +39 -28
- recce/apis/check_func.py +33 -27
- recce/apis/run_api.py +25 -19
- recce/apis/run_func.py +29 -23
- recce/artifact.py +44 -49
- recce/cli.py +484 -285
- recce/config.py +42 -33
- recce/core.py +52 -44
- recce/data/404.html +1 -1
- recce/data/_next/static/chunks/{368-7587b306577df275.js → 778-aef312bffb4c0312.js} +15 -15
- recce/data/_next/static/chunks/8d700b6a.ed11a130057c7a47.js +1 -0
- recce/data/_next/static/chunks/app/layout-c713a2829d3279e4.js +1 -0
- recce/data/_next/static/chunks/app/page-7086764277331fcb.js +1 -0
- recce/data/_next/static/chunks/{cd9f8d63-cf0d5a7b0f7a92e8.js → cd9f8d63-e020f408095ed77c.js} +3 -3
- recce/data/_next/static/chunks/webpack-b787cb1a4f2293de.js +1 -0
- recce/data/_next/static/css/88b8abc134cfd59a.css +3 -0
- recce/data/index.html +2 -2
- recce/data/index.txt +2 -2
- recce/diff.py +6 -12
- recce/event/__init__.py +74 -72
- recce/event/collector.py +27 -20
- recce/event/track.py +39 -27
- recce/exceptions.py +1 -1
- recce/git.py +7 -7
- recce/github.py +57 -53
- recce/models/__init__.py +1 -1
- recce/models/check.py +6 -7
- recce/models/run.py +1 -0
- recce/models/types.py +27 -27
- recce/pull_request.py +26 -24
- recce/run.py +148 -111
- recce/server.py +103 -89
- recce/state.py +209 -177
- recce/summary.py +168 -143
- recce/tasks/__init__.py +3 -3
- recce/tasks/core.py +11 -13
- recce/tasks/dataframe.py +19 -17
- recce/tasks/histogram.py +69 -34
- recce/tasks/lineage.py +2 -2
- recce/tasks/profile.py +147 -86
- recce/tasks/query.py +139 -87
- recce/tasks/rowcount.py +33 -30
- recce/tasks/schema.py +14 -14
- recce/tasks/top_k.py +35 -35
- recce/tasks/valuediff.py +216 -152
- recce/util/breaking.py +77 -84
- recce/util/cll.py +55 -51
- recce/util/io.py +19 -17
- recce/util/logger.py +1 -1
- recce/util/recce_cloud.py +70 -72
- recce/util/singleton.py +4 -4
- recce/yaml/__init__.py +7 -10
- {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250514.dist-info}/METADATA +5 -2
- recce_nightly-1.4.0.20250514.dist-info/RECORD +143 -0
- {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250514.dist-info}/WHEEL +1 -1
- tests/adapter/dbt_adapter/conftest.py +1 -0
- tests/adapter/dbt_adapter/dbt_test_helper.py +28 -18
- tests/adapter/dbt_adapter/test_dbt_adapter.py +0 -15
- tests/adapter/dbt_adapter/test_dbt_cll.py +39 -32
- tests/adapter/dbt_adapter/test_selector.py +22 -21
- tests/tasks/test_histogram.py +58 -66
- tests/tasks/test_lineage.py +36 -23
- tests/tasks/test_preset_checks.py +45 -31
- tests/tasks/test_profile.py +340 -15
- tests/tasks/test_query.py +40 -40
- tests/tasks/test_row_count.py +65 -46
- tests/tasks/test_schema.py +65 -42
- tests/tasks/test_top_k.py +22 -18
- tests/tasks/test_valuediff.py +43 -32
- tests/test_cli.py +71 -58
- tests/test_config.py +7 -9
- tests/test_core.py +5 -3
- tests/test_dbt.py +7 -7
- tests/test_pull_request.py +1 -1
- tests/test_server.py +19 -13
- tests/test_state.py +40 -27
- tests/test_summary.py +18 -14
- recce/data/_next/static/chunks/8d700b6a-f0b1f6b9e0d97ce2.js +0 -1
- recce/data/_next/static/chunks/app/layout-9102e22cb73f74d6.js +0 -1
- recce/data/_next/static/chunks/app/page-92f13c8fad9fae3d.js +0 -1
- recce/data/_next/static/chunks/webpack-567d72f0bc0820d5.js +0 -1
- recce_nightly-1.3.0.20250507.dist-info/RECORD +0 -142
- /recce/data/_next/static/{K5iKlCYhdcpq8Ea6ck9J_ → E_HPXsXdrqHg2YEHmU3mK}/_buildManifest.js +0 -0
- /recce/data/_next/static/{K5iKlCYhdcpq8Ea6ck9J_ → E_HPXsXdrqHg2YEHmU3mK}/_ssgManifest.js +0 -0
- {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250514.dist-info}/entry_points.txt +0 -0
- {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250514.dist-info}/licenses/LICENSE +0 -0
- {recce_nightly-1.3.0.20250507.dist-info → recce_nightly-1.4.0.20250514.dist-info}/top_level.txt +0 -0
recce/util/io.py
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import gzip
|
|
2
2
|
import os
|
|
3
3
|
import tempfile
|
|
4
|
-
from abc import ABCMeta, abstractmethod
|
|
4
|
+
from abc import ABC, ABCMeta, abstractmethod
|
|
5
5
|
from enum import Enum
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class SupportedFileTypes(Enum):
|
|
9
|
-
FILE =
|
|
10
|
-
GZIP =
|
|
11
|
-
ZIP =
|
|
9
|
+
FILE = "file"
|
|
10
|
+
GZIP = "gzip"
|
|
11
|
+
ZIP = "zip"
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def file_io_factory(file_type: SupportedFileTypes):
|
|
@@ -19,7 +19,7 @@ def file_io_factory(file_type: SupportedFileTypes):
|
|
|
19
19
|
elif file_type == SupportedFileTypes.ZIP:
|
|
20
20
|
return ZipFileIO
|
|
21
21
|
else:
|
|
22
|
-
raise ValueError(f
|
|
22
|
+
raise ValueError(f"Unsupported file type: {file_type}")
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class AbstractFileIO(metaclass=ABCMeta):
|
|
@@ -37,24 +37,24 @@ class AbstractFileIO(metaclass=ABCMeta):
|
|
|
37
37
|
class FileIO(AbstractFileIO, ABC):
|
|
38
38
|
@staticmethod
|
|
39
39
|
def write(path: str, data: str, **kwargs):
|
|
40
|
-
with open(path,
|
|
40
|
+
with open(path, "w") as f:
|
|
41
41
|
f.write(data)
|
|
42
42
|
|
|
43
43
|
@staticmethod
|
|
44
44
|
def read(path: str, **kwargs) -> str:
|
|
45
|
-
with open(path,
|
|
45
|
+
with open(path, "r") as f:
|
|
46
46
|
return f.read()
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
class GzipFileIO(AbstractFileIO, ABC):
|
|
50
50
|
@staticmethod
|
|
51
51
|
def write(path: str, data: str, **kwargs):
|
|
52
|
-
with gzip.open(path,
|
|
52
|
+
with gzip.open(path, "wt") as f:
|
|
53
53
|
f.write(data)
|
|
54
54
|
|
|
55
55
|
@staticmethod
|
|
56
56
|
def read(path: str, **kwargs) -> str:
|
|
57
|
-
with gzip.open(path,
|
|
57
|
+
with gzip.open(path, "rt") as f:
|
|
58
58
|
return f.read()
|
|
59
59
|
|
|
60
60
|
@staticmethod
|
|
@@ -69,17 +69,18 @@ class ZipFileIO(AbstractFileIO, ABC):
|
|
|
69
69
|
try:
|
|
70
70
|
import pyminizip
|
|
71
71
|
except ImportError:
|
|
72
|
-
raise ImportError(
|
|
72
|
+
raise ImportError("pyminizip is not installed. Please install it using `pip install pyminizip`")
|
|
73
73
|
|
|
74
74
|
@staticmethod
|
|
75
75
|
def read(path: str, **kwargs) -> str:
|
|
76
76
|
ZipFileIO._is_pyminizip_installed()
|
|
77
77
|
import pyminizip
|
|
78
|
+
|
|
78
79
|
cwd = os.getcwd()
|
|
79
|
-
password = kwargs.get(
|
|
80
|
-
zip_dir_name = kwargs.get(
|
|
80
|
+
password = kwargs.get("password")
|
|
81
|
+
zip_dir_name = kwargs.get("zip_dir_name")
|
|
81
82
|
if zip_dir_name is None:
|
|
82
|
-
raise ValueError(
|
|
83
|
+
raise ValueError("zip_dir_name is required for zipping")
|
|
83
84
|
|
|
84
85
|
try:
|
|
85
86
|
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
@@ -88,7 +89,7 @@ class ZipFileIO(AbstractFileIO, ABC):
|
|
|
88
89
|
content = FileIO.read(tmp_file)
|
|
89
90
|
except Exception as e:
|
|
90
91
|
error_msg = str(e)
|
|
91
|
-
if
|
|
92
|
+
if "-3" in error_msg:
|
|
92
93
|
raise Exception("Invalid password to uncompress state file.")
|
|
93
94
|
raise Exception(f"Failed to uncompress state file: {error_msg}")
|
|
94
95
|
finally:
|
|
@@ -100,11 +101,12 @@ class ZipFileIO(AbstractFileIO, ABC):
|
|
|
100
101
|
def write(path: str, data: str, **kwargs):
|
|
101
102
|
ZipFileIO._is_pyminizip_installed()
|
|
102
103
|
import pyminizip
|
|
104
|
+
|
|
103
105
|
cwd = os.getcwd()
|
|
104
|
-
password = kwargs.get(
|
|
105
|
-
zip_dir_name = kwargs.get(
|
|
106
|
+
password = kwargs.get("password")
|
|
107
|
+
zip_dir_name = kwargs.get("zip_dir_name")
|
|
106
108
|
if zip_dir_name is None:
|
|
107
|
-
raise ValueError(
|
|
109
|
+
raise ValueError("zip_dir_name is required for zipping")
|
|
108
110
|
|
|
109
111
|
try:
|
|
110
112
|
with tempfile.TemporaryDirectory() as tmp_dir:
|
recce/util/logger.py
CHANGED
|
@@ -16,7 +16,7 @@ class CustomFormatter(logging.Formatter):
|
|
|
16
16
|
logging.INFO: green + format + reset,
|
|
17
17
|
logging.WARNING: yellow + format + reset,
|
|
18
18
|
logging.ERROR: red + format + reset,
|
|
19
|
-
logging.CRITICAL: bold_red + format + reset
|
|
19
|
+
logging.CRITICAL: bold_red + format + reset,
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
def format(self, record):
|
recce/util/recce_cloud.py
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import logging
|
|
3
3
|
import os
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import IO, Dict
|
|
5
5
|
|
|
6
6
|
import requests
|
|
7
7
|
|
|
8
8
|
from recce.pull_request import PullRequestInfo
|
|
9
9
|
|
|
10
|
-
RECCE_CLOUD_API_HOST = os.environ.get(
|
|
10
|
+
RECCE_CLOUD_API_HOST = os.environ.get("RECCE_CLOUD_API_HOST", "https://cloud.datarecce.io")
|
|
11
11
|
|
|
12
|
-
logger = logging.getLogger(
|
|
12
|
+
logger = logging.getLogger("uvicorn")
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class PresignedUrlMethod:
|
|
16
|
-
UPLOAD =
|
|
17
|
-
DOWNLOAD =
|
|
16
|
+
UPLOAD = "upload"
|
|
17
|
+
DOWNLOAD = "download"
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class RecceCloudException(Exception):
|
|
@@ -23,7 +23,7 @@ class RecceCloudException(Exception):
|
|
|
23
23
|
self.status_code = status_code
|
|
24
24
|
|
|
25
25
|
try:
|
|
26
|
-
reason = json.loads(reason).get(
|
|
26
|
+
reason = json.loads(reason).get("detail", "")
|
|
27
27
|
except json.JSONDecodeError:
|
|
28
28
|
pass
|
|
29
29
|
self.reason = reason
|
|
@@ -32,134 +32,132 @@ class RecceCloudException(Exception):
|
|
|
32
32
|
class RecceCloud:
|
|
33
33
|
def __init__(self, token: str):
|
|
34
34
|
self.token = token
|
|
35
|
-
self.base_url = f
|
|
35
|
+
self.base_url = f"{RECCE_CLOUD_API_HOST}/api/v1"
|
|
36
36
|
|
|
37
37
|
def _request(self, method, url, **kwargs):
|
|
38
|
-
headers = {
|
|
39
|
-
'Authorization': f'Bearer {self.token}'
|
|
40
|
-
}
|
|
38
|
+
headers = {"Authorization": f"Bearer {self.token}"}
|
|
41
39
|
return requests.request(method, url, headers=headers, **kwargs)
|
|
42
40
|
|
|
43
|
-
def get_presigned_url(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
41
|
+
def get_presigned_url(
|
|
42
|
+
self,
|
|
43
|
+
method: PresignedUrlMethod,
|
|
44
|
+
repository: str,
|
|
45
|
+
artifact_name: str,
|
|
46
|
+
metadata: dict = None,
|
|
47
|
+
pr_id: int = None,
|
|
48
|
+
branch: str = None,
|
|
49
|
+
) -> str:
|
|
50
50
|
response = self._fetch_presigned_url(method, repository, artifact_name, metadata, pr_id, branch)
|
|
51
|
-
return response.get(
|
|
51
|
+
return response.get("presigned_url")
|
|
52
52
|
|
|
53
|
-
def get_download_presigned_url_with_tags(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
branch: str = None) -> (str, dict):
|
|
53
|
+
def get_download_presigned_url_with_tags(
|
|
54
|
+
self, repository: str, artifact_name: str, branch: str = None
|
|
55
|
+
) -> (str, dict):
|
|
57
56
|
response = self._fetch_presigned_url(PresignedUrlMethod.DOWNLOAD, repository, artifact_name, branch=branch)
|
|
58
|
-
return response.get(
|
|
59
|
-
|
|
60
|
-
def _fetch_presigned_url(
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
return response.get("presigned_url"), response.get("tags", {})
|
|
58
|
+
|
|
59
|
+
def _fetch_presigned_url(
|
|
60
|
+
self,
|
|
61
|
+
method: PresignedUrlMethod,
|
|
62
|
+
repository: str,
|
|
63
|
+
artifact_name: str,
|
|
64
|
+
metadata: dict = None,
|
|
65
|
+
pr_id: int = None,
|
|
66
|
+
branch: str = None,
|
|
67
|
+
) -> str:
|
|
67
68
|
if pr_id is not None:
|
|
68
|
-
api_url = f
|
|
69
|
+
api_url = f"{self.base_url}/{repository}/pulls/{pr_id}/artifacts/{method}?artifact_name={artifact_name}&enable_ssec=true"
|
|
69
70
|
elif branch is not None:
|
|
70
|
-
api_url = f
|
|
71
|
+
api_url = f"{self.base_url}/{repository}/commits/{branch}/artifacts/{method}?artifact_name={artifact_name}&enable_ssec=true"
|
|
71
72
|
else:
|
|
72
|
-
raise ValueError(
|
|
73
|
-
response = self._request(
|
|
73
|
+
raise ValueError("Either pr_id or sha must be provided.")
|
|
74
|
+
response = self._request("POST", api_url, json=metadata)
|
|
74
75
|
if response.status_code != 200:
|
|
75
76
|
raise RecceCloudException(
|
|
76
|
-
message=
|
|
77
|
-
method=method,
|
|
78
|
-
preposition='from' if method == PresignedUrlMethod.DOWNLOAD else 'to'
|
|
77
|
+
message="Failed to {method} artifact {preposition} Recce Cloud.".format(
|
|
78
|
+
method=method, preposition="from" if method == PresignedUrlMethod.DOWNLOAD else "to"
|
|
79
79
|
),
|
|
80
80
|
reason=response.text,
|
|
81
|
-
status_code=response.status_code
|
|
81
|
+
status_code=response.status_code,
|
|
82
82
|
)
|
|
83
83
|
return response.json()
|
|
84
84
|
|
|
85
85
|
def get_artifact_metadata(self, pr_info: PullRequestInfo) -> dict:
|
|
86
|
-
api_url = f
|
|
87
|
-
response = self._request(
|
|
86
|
+
api_url = f"{self.base_url}/{pr_info.repository}/pulls/{pr_info.id}/metadata"
|
|
87
|
+
response = self._request("GET", api_url)
|
|
88
88
|
if response.status_code == 204:
|
|
89
89
|
return None
|
|
90
90
|
if response.status_code != 200:
|
|
91
91
|
raise RecceCloudException(
|
|
92
|
-
message=
|
|
92
|
+
message="Failed to get artifact metadata from Recce Cloud.",
|
|
93
93
|
reason=response.text,
|
|
94
|
-
status_code=response.status_code
|
|
94
|
+
status_code=response.status_code,
|
|
95
95
|
)
|
|
96
96
|
return response.json()
|
|
97
97
|
|
|
98
98
|
def purge_artifacts(self, pr_info: PullRequestInfo):
|
|
99
|
-
api_url = f
|
|
100
|
-
response = self._request(
|
|
99
|
+
api_url = f"{self.base_url}/{pr_info.repository}/pulls/{pr_info.id}/artifacts"
|
|
100
|
+
response = self._request("DELETE", api_url)
|
|
101
101
|
if response.status_code != 204:
|
|
102
102
|
raise RecceCloudException(
|
|
103
|
-
message=
|
|
103
|
+
message="Failed to purge artifacts from Recce Cloud.",
|
|
104
104
|
reason=response.text,
|
|
105
|
-
status_code=response.status_code
|
|
105
|
+
status_code=response.status_code,
|
|
106
106
|
)
|
|
107
107
|
|
|
108
108
|
def check_artifacts_exists(self, pr_info: PullRequestInfo) -> bool:
|
|
109
|
-
api_url = f
|
|
110
|
-
response = self._request(
|
|
109
|
+
api_url = f"{self.base_url}/{pr_info.repository}/pulls/{pr_info.id}/metadata"
|
|
110
|
+
response = self._request("GET", api_url)
|
|
111
111
|
if response.status_code == 200:
|
|
112
112
|
return True
|
|
113
113
|
elif response.status_code == 204:
|
|
114
114
|
return False
|
|
115
115
|
else:
|
|
116
116
|
raise RecceCloudException(
|
|
117
|
-
message=
|
|
117
|
+
message="Failed to check if artifacts exist in Recce Cloud.",
|
|
118
118
|
reason=response.text,
|
|
119
|
-
status_code=response.status_code
|
|
119
|
+
status_code=response.status_code,
|
|
120
120
|
)
|
|
121
121
|
|
|
122
122
|
def share_state(self, file_name: str, file_io: IO):
|
|
123
|
-
api_url = f
|
|
124
|
-
files = {
|
|
125
|
-
response = self._request(
|
|
123
|
+
api_url = f"{self.base_url}/recce-state/upload"
|
|
124
|
+
files = {"file": (file_name, file_io, "application/json")}
|
|
125
|
+
response = self._request("POST", api_url, files=files)
|
|
126
126
|
if response.status_code == 403:
|
|
127
|
-
return {
|
|
127
|
+
return {"status": "error", "message": response.json().get("detail")}
|
|
128
128
|
if response.status_code != 200:
|
|
129
129
|
raise RecceCloudException(
|
|
130
|
-
message=
|
|
131
|
-
reason=response.text,
|
|
132
|
-
status_code=response.status_code
|
|
130
|
+
message="Failed to share Recce state.", reason=response.text, status_code=response.status_code
|
|
133
131
|
)
|
|
134
132
|
return response.json()
|
|
135
133
|
|
|
136
134
|
def update_github_pull_request_check(self, pr_info: PullRequestInfo, metadata: dict = None):
|
|
137
|
-
api_url = f
|
|
135
|
+
api_url = f"{self.base_url}/{pr_info.repository}/pulls/{pr_info.id}/github/checks"
|
|
138
136
|
try:
|
|
139
|
-
self._request(
|
|
137
|
+
self._request("POST", api_url, json=metadata)
|
|
140
138
|
except Exception as e:
|
|
141
139
|
# We don't care the response of this request, so we don't need to raise any exception.
|
|
142
|
-
logger.debug(f
|
|
140
|
+
logger.debug(f"Failed to update the GitHub PR check. Reason: {str(e)}")
|
|
143
141
|
|
|
144
142
|
def get_user_info(self) -> Dict:
|
|
145
|
-
api_url = f
|
|
146
|
-
response = self._request(
|
|
143
|
+
api_url = f"{self.base_url}/users"
|
|
144
|
+
response = self._request("GET", api_url)
|
|
147
145
|
if response.status_code != 200:
|
|
148
146
|
raise RecceCloudException(
|
|
149
|
-
message=
|
|
147
|
+
message="Failed to get user info from Recce Cloud.",
|
|
150
148
|
reason=response.text,
|
|
151
|
-
status_code=response.status_code
|
|
149
|
+
status_code=response.status_code,
|
|
152
150
|
)
|
|
153
|
-
return response.json().get(
|
|
151
|
+
return response.json().get("user")
|
|
154
152
|
|
|
155
153
|
def set_onboarding_state(self, state: str):
|
|
156
|
-
api_url = f
|
|
157
|
-
response = self._request(
|
|
154
|
+
api_url = f"{self.base_url}/users/onboarding-state"
|
|
155
|
+
response = self._request("PUT", api_url, json={"state": state})
|
|
158
156
|
if response.status_code != 200:
|
|
159
157
|
raise RecceCloudException(
|
|
160
|
-
message=
|
|
158
|
+
message="Failed to update onboarding state in Recce Cloud.",
|
|
161
159
|
reason=response.text,
|
|
162
|
-
status_code=response.status_code
|
|
160
|
+
status_code=response.status_code,
|
|
163
161
|
)
|
|
164
162
|
|
|
165
163
|
|
|
@@ -168,10 +166,10 @@ def get_recce_cloud_onboarding_state(token: str) -> str:
|
|
|
168
166
|
recce_cloud = RecceCloud(token)
|
|
169
167
|
user_info = recce_cloud.get_user_info()
|
|
170
168
|
if user_info:
|
|
171
|
-
return user_info.get(
|
|
169
|
+
return user_info.get("onboarding_state")
|
|
172
170
|
except Exception as e:
|
|
173
171
|
logger.debug(str(e))
|
|
174
|
-
return
|
|
172
|
+
return "undefined"
|
|
175
173
|
|
|
176
174
|
|
|
177
175
|
def set_recce_cloud_onboarding_state(token: str, new_state: str):
|
recce/util/singleton.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
class SingletonMeta(type):
|
|
2
2
|
"""
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
The Singleton class can be implemented in different ways in Python. Some
|
|
4
|
+
possible methods include: base class, decorator, metaclass. We will use the
|
|
5
|
+
metaclass because it is best suited for this purpose.
|
|
6
|
+
"""
|
|
7
7
|
|
|
8
8
|
_instances = {}
|
|
9
9
|
|
recce/yaml/__init__.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
from typing import Any, Callable
|
|
2
2
|
|
|
3
3
|
from ruamel import yaml
|
|
4
|
-
from ruamel.yaml import CommentedMap as _cm
|
|
4
|
+
from ruamel.yaml import CommentedMap as _cm
|
|
5
|
+
from ruamel.yaml import CommentedSeq as _cs
|
|
5
6
|
|
|
6
7
|
_yaml = yaml.YAML()
|
|
7
|
-
_safe_yaml = yaml.YAML(typ=
|
|
8
|
+
_safe_yaml = yaml.YAML(typ="safe")
|
|
8
9
|
|
|
9
10
|
CommentedMap = _cm
|
|
10
11
|
CommentedSeq = _cs
|
|
@@ -27,15 +28,13 @@ def safe_load(stream, version=None) -> Any:
|
|
|
27
28
|
return _safe_yaml.load(stream)
|
|
28
29
|
|
|
29
30
|
|
|
30
|
-
def dump(
|
|
31
|
-
data, stream: Any = None, *, transform: Any = None
|
|
32
|
-
) -> Any:
|
|
31
|
+
def dump(data, stream: Any = None, *, transform: Any = None) -> Any:
|
|
33
32
|
return _yaml.dump(data, stream, transform=transform)
|
|
34
33
|
|
|
35
34
|
|
|
36
35
|
def safe_load_yaml(file_path):
|
|
37
36
|
try:
|
|
38
|
-
with open(file_path,
|
|
37
|
+
with open(file_path, "r") as f:
|
|
39
38
|
payload = safe_load(f)
|
|
40
39
|
except yaml.YAMLError as e:
|
|
41
40
|
print(e)
|
|
@@ -46,7 +45,7 @@ def safe_load_yaml(file_path):
|
|
|
46
45
|
|
|
47
46
|
|
|
48
47
|
def round_trip_load_yaml(file_path):
|
|
49
|
-
with open(file_path,
|
|
48
|
+
with open(file_path, "r") as f:
|
|
50
49
|
try:
|
|
51
50
|
payload = load(f)
|
|
52
51
|
except yaml.YAMLError as e:
|
|
@@ -55,7 +54,5 @@ def round_trip_load_yaml(file_path):
|
|
|
55
54
|
return payload
|
|
56
55
|
|
|
57
56
|
|
|
58
|
-
def round_trip_dump(
|
|
59
|
-
data: Any,
|
|
60
|
-
stream=None):
|
|
57
|
+
def round_trip_dump(data: Any, stream=None):
|
|
61
58
|
return yaml.round_trip_dump(data, stream)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: recce-nightly
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0.20250514
|
|
4
4
|
Summary: Environment diff tool for dbt
|
|
5
5
|
Home-page: https://github.com/InfuseAI/recce
|
|
6
6
|
Author: InfuseAI Dev Team
|
|
@@ -40,7 +40,10 @@ Requires-Dist: sqlglot
|
|
|
40
40
|
Provides-Extra: dev
|
|
41
41
|
Requires-Dist: pytest>=4.6; extra == "dev"
|
|
42
42
|
Requires-Dist: pytest-flake8; extra == "dev"
|
|
43
|
-
Requires-Dist:
|
|
43
|
+
Requires-Dist: black>=25.1.0; extra == "dev"
|
|
44
|
+
Requires-Dist: isort>=6.0.1; extra == "dev"
|
|
45
|
+
Requires-Dist: flake8>=7.2.0; extra == "dev"
|
|
46
|
+
Requires-Dist: pre-commit>=4.2.0; extra == "dev"
|
|
44
47
|
Requires-Dist: pytest-mypy; extra == "dev"
|
|
45
48
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
46
49
|
Requires-Dist: twine; extra == "dev"
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
recce/VERSION,sha256=9ZTNVW7MlcEiwz3qySDm_h-tOLFOykEntdSn8SASwaU,15
|
|
2
|
+
recce/__init__.py,sha256=yNb0QT-yoStex0VZALNJvUwtPLommoVCStcow31guqo,2392
|
|
3
|
+
recce/artifact.py,sha256=tKQAHSrLRjiR3ppOI4sym8SxYiiLTuD3DPMYh4DWQdA,6506
|
|
4
|
+
recce/cli.py,sha256=OqIUMkQSm1XgpGawm_j1XURAMK9ijlBQrWTuakPP6S0,35388
|
|
5
|
+
recce/config.py,sha256=fs22mpFj8CFIxftGbhFAV5xIsPLX2xNTwWSer3UYn5k,4658
|
|
6
|
+
recce/core.py,sha256=C7RooEojAi5PIlbJuvB0Cj8F0HVktyn8bNRZE-TuzHQ,10726
|
|
7
|
+
recce/diff.py,sha256=L2_bzQ3__PO-0aeir8PHF8FvSOUmQ8WcDXgML1-mHdY,748
|
|
8
|
+
recce/exceptions.py,sha256=SclQ678GrHGjw7p_ZFJ3vZaL_yMU5xABeIAm2u_W2bk,592
|
|
9
|
+
recce/git.py,sha256=8Eg-6NzL-KjA3rT-ibbAyaCwGlzV0JqH3yGikrJNMDA,2344
|
|
10
|
+
recce/github.py,sha256=PEpM6ZRiinsPbXSWj4aJCKbZrN1jUXzpzAfJq_CGah4,7420
|
|
11
|
+
recce/pull_request.py,sha256=aW0B1NE2LUKTam1S4TQ7smXB9KLE1DV8GnyBqNXA6j8,3832
|
|
12
|
+
recce/run.py,sha256=LAjbWUF8loZ9cL25d_maQELwROHHmfaFn7iqFRy5O1o,13567
|
|
13
|
+
recce/server.py,sha256=X7WDMlujxfzc8yk-GWuSyVIWee9kUEcjplGP1vD0r1w,20301
|
|
14
|
+
recce/state.py,sha256=VPzKyEdmyBeZ45BQArB587QN5C3Sfr7O5Oh_JRBcKrc,30616
|
|
15
|
+
recce/summary.py,sha256=Mbxvxr9KazR5o9icqhhjiGHsoAiWxQU4PdN7HytBJ1c,19154
|
|
16
|
+
recce/adapter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
|
+
recce/adapter/base.py,sha256=T_JNeLHgiHSaegw-DbrvHOaYjMyZcjj2Qtg5cWh_fco,3548
|
|
18
|
+
recce/adapter/sqlmesh_adapter.py,sha256=IU3N-F6ToDoO7_bV5vsG8pmTuDcbFtewTIuCxedTaRM,5046
|
|
19
|
+
recce/adapter/dbt_adapter/__init__.py,sha256=21FBwx6ovGO-oOxLcsZWVejlD35NT_r2v3vtApnWfTU,54384
|
|
20
|
+
recce/adapter/dbt_adapter/dbt_version.py,sha256=M7aedZIWslXnJsryK8Ki4OL_t2oAKxy4uE2pRwfWIkk,1228
|
|
21
|
+
recce/apis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
+
recce/apis/check_api.py,sha256=KMCXSMl1qqzx2jQgRqCrD4j_cY3EHBbM3H2-t-6saAU,6227
|
|
23
|
+
recce/apis/check_func.py,sha256=gktbCcyk3WGvWRJJ-wDnwv7NrIny2nTHWLl1-kdiVRo,4183
|
|
24
|
+
recce/apis/run_api.py,sha256=eOaxOxXDkH59uqGCd4blld7edavUx7JU_DCd2WAYrL8,3416
|
|
25
|
+
recce/apis/run_func.py,sha256=6wC8TDU-h7TLr2VZH7HNsWaUVlQ9HBN5N_dwqfi4lMY,7440
|
|
26
|
+
recce/data/404.html,sha256=-lVLhRLEsURSnKitVilsjDgmfn7nl9b5sf93tyLmBYw,6554
|
|
27
|
+
recce/data/favicon.ico,sha256=B2mBumUOnzvUrXrqNkrc5QfdDXjzEXRcWkWur0fJ6sM,2565
|
|
28
|
+
recce/data/index.html,sha256=0gl6lXkM8EKzI77w9mla9EyfHnVfaH2uua6bskSlYpo,40259
|
|
29
|
+
recce/data/index.txt,sha256=lwU7wJpAlhXZUhUNKdm1kJ3hxgADAdm55xKAAhCOjik,3514
|
|
30
|
+
recce/data/_next/static/E_HPXsXdrqHg2YEHmU3mK/_buildManifest.js,sha256=gZrGHi2LPMw1gkjYWs13MYkJyb5aOtihBRSJ1w0E6QA,224
|
|
31
|
+
recce/data/_next/static/E_HPXsXdrqHg2YEHmU3mK/_ssgManifest.js,sha256=Z49s4suAsf5y_GfnQSvm4qtq2ggxEbZPfEDTXjy6XgA,80
|
|
32
|
+
recce/data/_next/static/chunks/1f229bf6-d9fe92e56db8d93b.js,sha256=NvhILR-yLwIu-WlvwD9Hkr2H_I7ZK64vwYvR6c84wC0,172836
|
|
33
|
+
recce/data/_next/static/chunks/29e3cc0d-8c150e37dff9631b.js,sha256=4ZQR-OYMhGWnYPNwUjG5FpsTVzVTPEAf6T0v0E5g-4o,700
|
|
34
|
+
recce/data/_next/static/chunks/36e1c10d-bb0210cbd6573a8d.js,sha256=SkfIoUJXsrjEoql4hRRcWKtW2vMfHOAHUm4NE6eaho4,7797
|
|
35
|
+
recce/data/_next/static/chunks/3998a672-eaad84bdd88cc73e.js,sha256=7FRm86VFsyXQL6M4J0qFq7e4cvhs48uKJF2Qp0tYraM,9024
|
|
36
|
+
recce/data/_next/static/chunks/3a92ee20-3b5d922d4157af5e.js,sha256=Ou-yjvdFB0Zy_Im93w9LrR2LyB_aRnaNn1Sz1EB18mI,177688
|
|
37
|
+
recce/data/_next/static/chunks/450c323b-1bb5db526e54435a.js,sha256=3M8dU9CapPo-oey7uyaRBaSrnwoPHUQb671T-_Nv7bs,2205
|
|
38
|
+
recce/data/_next/static/chunks/47d8844f-79a1b53c66a7d7ec.js,sha256=WwhEczkWeoHd3z0pTrh4u_XwBoUxePZ7rjEMPjajmx8,697
|
|
39
|
+
recce/data/_next/static/chunks/6dc81886-c94b9b91bc2c3caf.js,sha256=xIxqOzAWk07uQb5pgQGMv0O4CHereLF86Fwm2wX0Mmo,69733
|
|
40
|
+
recce/data/_next/static/chunks/6ef81909-694dc38134099299.js,sha256=KiPoS30Exnv9fi1X2HvxnydUFJnWfY-ZeifdexVAEXA,49001
|
|
41
|
+
recce/data/_next/static/chunks/700-3b65fc3666820d00.js,sha256=JokVG7hi66aCWFukVWlzc2vIBKa7EFW7JrSGW9F_2tU,124133
|
|
42
|
+
recce/data/_next/static/chunks/778-aef312bffb4c0312.js,sha256=0r8zj3JFDP8_0FxXPE8b_4aeW2nmwYi8wh5GiWBY5VM,1361523
|
|
43
|
+
recce/data/_next/static/chunks/7a8a3e83-d7fa409d97b38b2b.js,sha256=MmsF3qQgQXqSPGhUHQbIqAtVz7Maa_O3rWErEq0N3gY,1649
|
|
44
|
+
recce/data/_next/static/chunks/7f27ae6c-413f6b869a04183a.js,sha256=8Hs6bhtsCfZiOFrX3_IBxLZKPsdqhkLzikrACS1Pe0M,779
|
|
45
|
+
recce/data/_next/static/chunks/8d700b6a.ed11a130057c7a47.js,sha256=ObDzyvm0pCB9K8yFyj5vin5cVzTr5IqVO4XD-KHtXmo,119972
|
|
46
|
+
recce/data/_next/static/chunks/9746af58-d74bef4d03eea6ab.js,sha256=9MwsjNv8XMd92eUpXYeA32Ahk8ORP_oWMXnpTYOQQ-c,4177
|
|
47
|
+
recce/data/_next/static/chunks/a30376cd-7d806e1602f2dc3a.js,sha256=cvkpSEaZn5Johnsf3DT_x-hKNlNIhYFb6CZcMqpXpTE,797
|
|
48
|
+
recce/data/_next/static/chunks/b63b1b3f-7395c74e11a14e95.js,sha256=g2ArwRSeMZ-o6dODDGh3orC0iRkyxjXTk4NgyVk1nBw,572
|
|
49
|
+
recce/data/_next/static/chunks/c132bf7d-8102037f9ccf372a.js,sha256=CSRe9MSZI7ohCFzU6umTdDDkw2aBiLhA0HLurQwrjUY,198537
|
|
50
|
+
recce/data/_next/static/chunks/c1ceaa8b-a1e442154d23515e.js,sha256=mL85IeBYKB6YBgKlDs2n5lA7iLaxU8nTEtE8jduhGRI,81302
|
|
51
|
+
recce/data/_next/static/chunks/cd9f8d63-e020f408095ed77c.js,sha256=GeYFrOTA_N2zLZhmnWoJJOzgo_Jc9hk8svIHuTysdUg,82989
|
|
52
|
+
recce/data/_next/static/chunks/ce84277d-f42c2c58049cea2d.js,sha256=4FzO_5dSRNQKZHQ2EmZW0iau4yBguMBJ324J0e70UXQ,2562
|
|
53
|
+
recce/data/_next/static/chunks/e24bf851-0f8cbc99656833e7.js,sha256=aaPLADhg4KN7KoE09dpPiE831gBYqepVrIJj6Qh2amk,154153
|
|
54
|
+
recce/data/_next/static/chunks/fee69bc6-f17d36c080742e74.js,sha256=r51nWC424b7AoD-Y68JLMXDDpS_n-IUL3zcJNStzOLA,483
|
|
55
|
+
recce/data/_next/static/chunks/framework-ded83d71b51ce901.js,sha256=0Xsxxnmw5fjRHz8ni6vlaF9tQjfjNGZcZv2oMy7A_T4,140000
|
|
56
|
+
recce/data/_next/static/chunks/main-a0859f1f36d0aa6c.js,sha256=nTSd5jisBq_nX5_3Yf1JMakSk9Rq5IQEhtzeFU0VRyY,111204
|
|
57
|
+
recce/data/_next/static/chunks/main-app-0225a2255968e566.js,sha256=zVNui79GYFi-pNlmSB_zwxzps-uRW9L1-HZXXBUFj-Y,471
|
|
58
|
+
recce/data/_next/static/chunks/polyfills-42372ed130431b0a.js,sha256=CXPB1kyIrcjjyVBBDLWLKI9yEY1ZZbeASUON648vloM,112594
|
|
59
|
+
recce/data/_next/static/chunks/webpack-b787cb1a4f2293de.js,sha256=JMFnMBlHCoK4ti0UmBLCfdf5Vb1lgvJm7C3nzW8KbbQ,3899
|
|
60
|
+
recce/data/_next/static/chunks/app/layout-c713a2829d3279e4.js,sha256=Y0QZ74X1tmZrRQBM1HhnrmFyKgQx4aKRPE4KL6KSh3I,233
|
|
61
|
+
recce/data/_next/static/chunks/app/page-7086764277331fcb.js,sha256=y_cRY7_yvMXI-PsE1gLWRz6rd07RP5H5zUVvrID-2fY,225920
|
|
62
|
+
recce/data/_next/static/chunks/app/_not-found/page-8a886fa0855c3105.js,sha256=T5MBvLNarbZQll8vwvggCZWFzcNwqe6LlL0hGI9YPXA,1751
|
|
63
|
+
recce/data/_next/static/chunks/pages/_app-d5672bf3d8b6371b.js,sha256=UcYdHJMmCNfuMevCyY_iFfFwMGbxcEkLGRbBnEx_cCU,284
|
|
64
|
+
recce/data/_next/static/chunks/pages/_error-ed75be3f25588548.js,sha256=o_MwN3cYfszhI-hy_wkB0XAyTgcEcXt43rrzk-oKIe0,250
|
|
65
|
+
recce/data/_next/static/css/88b8abc134cfd59a.css,sha256=Tb97QjWxV5rOawZojbeD9SSETGsG2p9iaOrENjzAjYM,7235
|
|
66
|
+
recce/data/_next/static/css/c9ecb46a4b21c126.css,sha256=JbGypR8aDNuZavNvH6dhPtSbMVSCsy0ycPrz_6XkiVc,21925
|
|
67
|
+
recce/data/_next/static/media/montserrat-cyrillic-800-normal.22628180.woff2,sha256=P5Sx5PNkdTlDYzAdulW_OPRfMokDLi6XTpmS8KJSRoI,11148
|
|
68
|
+
recce/data/_next/static/media/montserrat-cyrillic-800-normal.31d693bb.woff,sha256=ITxULbMzWscxwUi_v3GpzTSYVWlwq_z9fpEvAkEvHJw,11020
|
|
69
|
+
recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.7e2c1e62.woff,sha256=6J3PqBk_hOFVM8PpfZeSfwZQumQd6LTPPjnaVha2KQ0,12672
|
|
70
|
+
recce/data/_next/static/media/montserrat-cyrillic-ext-800-normal.94a63aea.woff2,sha256=qHQDcPj9VkK-6sE5nxIKvejtNLo5RwBULzyH9nZsEwo,12052
|
|
71
|
+
recce/data/_next/static/media/montserrat-latin-800-normal.6f8fa298.woff2,sha256=Tyiv8SvOCaTmT_S2FaOZ5FuZz52F1aVV9hzIfrI7sEI,19036
|
|
72
|
+
recce/data/_next/static/media/montserrat-latin-800-normal.97e20d5e.woff,sha256=O3hUbMaqKvL7tlGscLIlvxQbLpHgOmCRLfwQ6RjJvE0,20784
|
|
73
|
+
recce/data/_next/static/media/montserrat-latin-ext-800-normal.013b84f9.woff2,sha256=tOnyR2cgiUm1cKtlrN9CY6FzD2yAMBe90slHKC0cBms,33776
|
|
74
|
+
recce/data/_next/static/media/montserrat-latin-ext-800-normal.aff52ab0.woff,sha256=IaGLu1tg0bPED9SLQjsK_VdkG3_RCq82GBmSP56xNFU,41956
|
|
75
|
+
recce/data/_next/static/media/montserrat-vietnamese-800-normal.5f21869b.woff,sha256=9ke3AivSl-ihV218s2s9NyJS8t0ETKDdqIK4rJWiPl0,7544
|
|
76
|
+
recce/data/_next/static/media/montserrat-vietnamese-800-normal.c0035377.woff2,sha256=bnmP7vEVe-4gLSDBsmKqD-SATv6-Pg-pxnTpSj7BCeI,7948
|
|
77
|
+
recce/data/imgs/feedback/thumbs-down.png,sha256=q9KVIbaZku1TWkYHuleYlO-b6HsTApYh3St5xNHMGMg,10695
|
|
78
|
+
recce/data/imgs/feedback/thumbs-up.png,sha256=VF3BH8bmYEqcSsMDJO57xMqW4t6crCXUXaMlOPgI_OE,10556
|
|
79
|
+
recce/data/logo/recce-logo-white.png,sha256=y3re8iEucJnMUkAkRS2CjWHTlOydyvgWdWjuQKcXDbk,46923
|
|
80
|
+
recce/event/CONFIG,sha256=w8_AVcNu_JF-t8lNmjOqtsXbeOawMzpEhkISaMlm-iU,48
|
|
81
|
+
recce/event/SENTRY_DNS,sha256=nWXZevLC4qDScvNtjs329X13oxqvtFI_Kiu6cfCDOBA,83
|
|
82
|
+
recce/event/__init__.py,sha256=5yUqhpRUPejLbaQb7kRUXYtXUwqGYzm8ewga-PYmssQ,8387
|
|
83
|
+
recce/event/collector.py,sha256=1Y02A77CkMMrRv-5F1KUAMGebG7m3wXhsvcPdXM2Ugg,5661
|
|
84
|
+
recce/event/track.py,sha256=xDyDWblhR6mp0tezEYhkA0aOyZLqXBpJyHZwhI2xhU8,4803
|
|
85
|
+
recce/models/__init__.py,sha256=2ai4y8o0HfV358-qjSBBEC0KxqBwsdrbAdG2kT12mIo,104
|
|
86
|
+
recce/models/check.py,sha256=jjR1SGyczjrqyK-0Zas6ikLIGSgVp54lvfcQA19AniI,1588
|
|
87
|
+
recce/models/run.py,sha256=QK2gvOWvko9YYhd2NLs3BPt5l4MSCZGwpzTAiqx9zJw,1161
|
|
88
|
+
recce/models/types.py,sha256=leifP8zMuUcsK4nmtBlcI-Lz1mvDhGYg__POrR_hODg,3130
|
|
89
|
+
recce/tasks/__init__.py,sha256=qtOCHacoGndJ3MunCXe8HtYXpy8b-6jOl5ZCI5IuM2M,316
|
|
90
|
+
recce/tasks/core.py,sha256=JFYa1CfgOiRPQ7KVTwMuxJjhMB-pvCwB-xezVt-h3RU,4080
|
|
91
|
+
recce/tasks/dataframe.py,sha256=03UBWwt0DFTXlaEOtnV5i_mxdRKD7UbRayewEL2Ub48,3650
|
|
92
|
+
recce/tasks/histogram.py,sha256=SMdSznzrBdAFvAbhsoUGAK9o0QUMYy00IVbamUVTpBk,13601
|
|
93
|
+
recce/tasks/lineage.py,sha256=_PbY0ZkDr620U8V2olqoX_T9XA0-G8ILt_6m1Q5TfBs,541
|
|
94
|
+
recce/tasks/profile.py,sha256=gMgms9qvdDsihh2aSC6LvCm9ggah4Oq3xjvmCh_exrU,11352
|
|
95
|
+
recce/tasks/query.py,sha256=k3y_IK1_3D2j4Scw-70ccDjVMa-Oe9jqxlDyLHfjagw,12790
|
|
96
|
+
recce/tasks/rowcount.py,sha256=DIC17VUKtGhEHz6lW4VFLHyD6F4e4QV0i_Dsz4HAv1w,9750
|
|
97
|
+
recce/tasks/schema.py,sha256=HHrSvhd_ZJdrNj2QKi9W8vmig0NuYci5cgsKFvp2bu4,2274
|
|
98
|
+
recce/tasks/top_k.py,sha256=vY3VCBmg61E8I4V-9-hJOv5RCYCmhxl6sHiKR9Zv7eE,5521
|
|
99
|
+
recce/tasks/valuediff.py,sha256=XJWkA307B5qTerT87fJRhJxPCqjmXn5eILYCXDfPtSQ,16439
|
|
100
|
+
recce/util/__init__.py,sha256=0lcJectK7Z7k9h0EaYCcv4Bgw2PN03OdJoxb3tbV5j8,37
|
|
101
|
+
recce/util/breaking.py,sha256=_63SJhEqYVIsIp7SqXA9Muh2fDcvgjm9RhfZ3nTNJFQ,12593
|
|
102
|
+
recce/util/cache.py,sha256=QB6wzxe0M3jNTwP0M27Ys8F2hF-oda4-LyXXG9THuZQ,646
|
|
103
|
+
recce/util/cll.py,sha256=eg32KNz4Ec-FkOLSgMwP8TrW_TTUydI7xTb_UAbt-oI,12164
|
|
104
|
+
recce/util/io.py,sha256=53s4uDFT6ftpI-12MBxfv-RiBkWvPXMvdxPO9lJrjJM,3374
|
|
105
|
+
recce/util/lineage.py,sha256=C-jNqRARgwAEQoicO5t7D0XGBkcVs6SyxLzfzCAqkPQ,707
|
|
106
|
+
recce/util/logger.py,sha256=6UgLFkRiur9jJfu2ZRdo4LUvMw4f75V-l-1HT1-sgKo,747
|
|
107
|
+
recce/util/pydantic_model.py,sha256=KumKuyCjbTzEMsKLE4-b-eZfp0gLhYDdmVtw1-hxiJw,587
|
|
108
|
+
recce/util/recce_cloud.py,sha256=F9Y4zqUVqQAzbLrWnccJdSjGPHzhGCVBfN4mOGVwpL8,6822
|
|
109
|
+
recce/util/singleton.py,sha256=1cU99I0f9tjuMQLMJyLsK1oK3fZJMsO5-TbRHAMXqds,627
|
|
110
|
+
recce/yaml/__init__.py,sha256=EgXYlFeJZchatUClRDXbIC5Oqb2_nBvB2NqItYVihio,1292
|
|
111
|
+
recce_nightly-1.4.0.20250514.dist-info/licenses/LICENSE,sha256=CQjjMy9aYPhfe8xG_bcpIfKtNkdxLZ5IOb8oPygtUhY,11343
|
|
112
|
+
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
113
|
+
tests/test_cli.py,sha256=f0n15QNVAyCqkygwIUp2aaoNAQau1zZp-nXpK4yyf1E,5444
|
|
114
|
+
tests/test_config.py,sha256=ODDFe_XF6gphmSmmc422dGLBaCCmG-IjDzTkD5SJsJE,1557
|
|
115
|
+
tests/test_core.py,sha256=oDaZz1nrMxoi-3GwA7sRwCJjk99M6C7dyBqGiJmB62A,785
|
|
116
|
+
tests/test_dbt.py,sha256=n3-Y3NaJI8ewdBKGoOldsWpTedwzCZM4Cp_6UYaURo8,1323
|
|
117
|
+
tests/test_pull_request.py,sha256=HmZo5MoDaoKSgPwbLxJ3Ur3ajZ7IxhkzJxaOmhg6bwE,3562
|
|
118
|
+
tests/test_server.py,sha256=7MYAr3ZvLIeFQ_DlvUW9sgV7wBr0gDMJchEC97zup8M,3383
|
|
119
|
+
tests/test_state.py,sha256=p6rIwEh78GBBocqv98elX14WzqrpXNpnfd4uWI8u1bI,5022
|
|
120
|
+
tests/test_summary.py,sha256=D0WvAkdO-vzGcvholH2rfS1wTxUXjVHwWm59fWy45eA,2876
|
|
121
|
+
tests/adapter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
122
|
+
tests/adapter/dbt_adapter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
123
|
+
tests/adapter/dbt_adapter/conftest.py,sha256=bLPgVhwLZpHsYm1bf7CrjNwqu3XZQuzc7CJDjbu8qZk,272
|
|
124
|
+
tests/adapter/dbt_adapter/dbt_test_helper.py,sha256=6yvz8UXzzFyNaL2uUHjJm1zPlhe2PUEpnkH737iRTjQ,9957
|
|
125
|
+
tests/adapter/dbt_adapter/test_dbt_adapter.py,sha256=Y5TSlqkXGjJC6hC7YYs45bnRht5aou_KLjPMjpAGxNM,830
|
|
126
|
+
tests/adapter/dbt_adapter/test_dbt_cll.py,sha256=J_jZ3am8czzSWDxW08Fw1gSggziPBH0pl8bJmz7uFQE,4109
|
|
127
|
+
tests/adapter/dbt_adapter/test_selector.py,sha256=uKFm0QxrxG-xyUEXGobCMueCRUssgnZMyo-S1Nlk3_s,6856
|
|
128
|
+
tests/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
129
|
+
tests/tasks/conftest.py,sha256=UefgbNfJufLOmgHLiEFXIjOVmu8-58GbS6m5-NcEu20,143
|
|
130
|
+
tests/tasks/test_histogram.py,sha256=g69R2Ljvcd8RQTnq7EMZEa93_1vVWNe4ZLg990rWuyA,4088
|
|
131
|
+
tests/tasks/test_lineage.py,sha256=HODSP2_uSu98e4jV-t9TIOSrln_5mXd-6baKv9aEmws,1095
|
|
132
|
+
tests/tasks/test_preset_checks.py,sha256=fAro5kAv67YiXgRFj7hDAgZEd8fVSHW_VTapVDq4G04,1457
|
|
133
|
+
tests/tasks/test_profile.py,sha256=c26igXN1r6sw-iDf79Skis3B-q2o3VPRamQCuZ43GfY,10262
|
|
134
|
+
tests/tasks/test_query.py,sha256=_Lnew7hVEaFtZs3hWcTgF67YFtgE7AkDVdWyLr9oF5E,4253
|
|
135
|
+
tests/tasks/test_row_count.py,sha256=21PaP2aq-x8-pqwzWHRT1sixhQ8g3CQNRWOZTTmbK0s,3151
|
|
136
|
+
tests/tasks/test_schema.py,sha256=7ds4Vx8ixaiIWDR49Lvjem4xlPkRP1cXazDRY3roUak,3121
|
|
137
|
+
tests/tasks/test_top_k.py,sha256=YR_GS__DJsbDlQVaEEdJvNQ3fh1VmV5Nb3G7lb0r6YM,1779
|
|
138
|
+
tests/tasks/test_valuediff.py,sha256=_xQJGgxsXoy2NYk_Z6Hsw2FlVh6zk2nN_iUueyRN1e8,2046
|
|
139
|
+
recce_nightly-1.4.0.20250514.dist-info/METADATA,sha256=UDAsDhfJj9EFwSQ3lrAYIKAIEbg7eH7MIRTNheALq7A,9299
|
|
140
|
+
recce_nightly-1.4.0.20250514.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
|
|
141
|
+
recce_nightly-1.4.0.20250514.dist-info/entry_points.txt,sha256=oqoY_IiwIqXbgrIsPnlqUqao2eiIeP2dprowkOlmeyg,40
|
|
142
|
+
recce_nightly-1.4.0.20250514.dist-info/top_level.txt,sha256=6PKGVpf75idP0C6KEaldDzzZUauIxNu1ZDstau1pI4I,12
|
|
143
|
+
recce_nightly-1.4.0.20250514.dist-info/RECORD,,
|