dataflow-core 2.1.15rc4__py3-none-any.whl → 2.1.16__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 dataflow-core might be problematic. Click here for more details.
- dataflow/dataflow.py +100 -0
- dataflow/environment.py +6 -3
- dataflow/scripts/clone_environment.sh +4 -0
- {dataflow_core-2.1.15rc4.dist-info → dataflow_core-2.1.16.dist-info}/METADATA +1 -1
- {dataflow_core-2.1.15rc4.dist-info → dataflow_core-2.1.16.dist-info}/RECORD +8 -8
- {dataflow_core-2.1.15rc4.dist-info → dataflow_core-2.1.16.dist-info}/WHEEL +0 -0
- {dataflow_core-2.1.15rc4.dist-info → dataflow_core-2.1.16.dist-info}/entry_points.txt +0 -0
- {dataflow_core-2.1.15rc4.dist-info → dataflow_core-2.1.16.dist-info}/top_level.txt +0 -0
dataflow/dataflow.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import os, requests
|
|
2
2
|
from .database_manager import DatabaseManager
|
|
3
3
|
import json
|
|
4
|
+
import base64
|
|
4
5
|
from .configuration import ConfigurationManager
|
|
5
6
|
|
|
6
7
|
|
|
@@ -177,6 +178,105 @@ class Dataflow:
|
|
|
177
178
|
except Exception as e:
|
|
178
179
|
print(f"[Dataflow.secret] Exception occurred: {e}")
|
|
179
180
|
return None
|
|
181
|
+
|
|
182
|
+
def secret_file(self, secret_name: str):
|
|
183
|
+
"""
|
|
184
|
+
Retrieve a Dataflow secret file.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
secret_name (str): Name of the secret to retrieve
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
str or None: Secret value if found, None otherwise
|
|
191
|
+
"""
|
|
192
|
+
try:
|
|
193
|
+
host_name = os.environ.get("HOSTNAME", "")
|
|
194
|
+
runtime = os.environ.get("RUNTIME")
|
|
195
|
+
slug = os.environ.get("SLUG")
|
|
196
|
+
org_id = os.environ.get("ORGANIZATION")
|
|
197
|
+
|
|
198
|
+
dataflow_config = ConfigurationManager('/dataflow/app/auth_config/dataflow_auth.cfg')
|
|
199
|
+
query_params = {
|
|
200
|
+
"key": secret_name
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if runtime:
|
|
204
|
+
secret_api = dataflow_config.get_config_value("auth", "secret_ui_api")
|
|
205
|
+
query_params["runtime"] = runtime
|
|
206
|
+
query_params["slug"] = slug
|
|
207
|
+
query_params["org_id"] = org_id
|
|
208
|
+
else:
|
|
209
|
+
secret_api = dataflow_config.get_config_value("auth", "secret_manager_api")
|
|
210
|
+
if not secret_api:
|
|
211
|
+
print("[Dataflow.secret] Secret API Unreachable")
|
|
212
|
+
return None
|
|
213
|
+
|
|
214
|
+
response = requests.get(secret_api, params=query_params)
|
|
215
|
+
|
|
216
|
+
if response.status_code == 404:
|
|
217
|
+
return None
|
|
218
|
+
elif response.status_code >= 500:
|
|
219
|
+
response.raise_for_status()
|
|
220
|
+
elif response.status_code >= 400:
|
|
221
|
+
print(f"[Dataflow.secret] Client error {response.status_code} for secret '{secret_name}'")
|
|
222
|
+
return None
|
|
223
|
+
elif response.status_code != 200:
|
|
224
|
+
print(f"[Dataflow.secret] Unexpected status {response.status_code} for secret '{secret_name}'")
|
|
225
|
+
return None
|
|
226
|
+
|
|
227
|
+
response_data = response.json()
|
|
228
|
+
if response.status_code == 200 and response_data.get('filename'):
|
|
229
|
+
# For runtime mode, create file and return filepath
|
|
230
|
+
if runtime:
|
|
231
|
+
import tempfile
|
|
232
|
+
from pathlib import Path
|
|
233
|
+
|
|
234
|
+
# Create /tmp/secrets directory if it doesn't exist
|
|
235
|
+
secrets_dir = Path("/tmp/secrets")
|
|
236
|
+
secrets_dir.mkdir(parents=True, exist_ok=True)
|
|
237
|
+
|
|
238
|
+
# Get filename and content
|
|
239
|
+
filename = response_data.get('filename')
|
|
240
|
+
file_content = response_data.get('value')
|
|
241
|
+
|
|
242
|
+
if not filename or not file_content:
|
|
243
|
+
print(f"[Dataflow.secret] Missing filename or content for secret '{secret_name}'")
|
|
244
|
+
return None
|
|
245
|
+
|
|
246
|
+
file_path = os.path.join(secrets_dir, filename)
|
|
247
|
+
|
|
248
|
+
# Detect if content is Base64 encoded binary or text
|
|
249
|
+
try:
|
|
250
|
+
# Try to decode as Base64
|
|
251
|
+
decoded_content = base64.b64decode(file_content, validate=True)
|
|
252
|
+
# Check if it contains non-printable characters (likely binary)
|
|
253
|
+
is_binary = not all(32 <= byte <= 126 or byte in (9, 10, 13) for byte in decoded_content[:100])
|
|
254
|
+
|
|
255
|
+
if is_binary:
|
|
256
|
+
# Write as binary
|
|
257
|
+
with open(file_path, 'wb') as f:
|
|
258
|
+
f.write(decoded_content)
|
|
259
|
+
else:
|
|
260
|
+
# Decode and write as text
|
|
261
|
+
with open(file_path, 'w', encoding='utf-8') as f:
|
|
262
|
+
f.write(decoded_content.decode('utf-8'))
|
|
263
|
+
except Exception:
|
|
264
|
+
# Not Base64 or decode failed, treat as text
|
|
265
|
+
with open(file_path, 'w', encoding='utf-8') as f:
|
|
266
|
+
f.write(file_content)
|
|
267
|
+
return str(file_path)
|
|
268
|
+
else:
|
|
269
|
+
# For non-runtime mode, return the value as-is
|
|
270
|
+
return response_data.get('value')
|
|
271
|
+
else:
|
|
272
|
+
print(f"[Dataflow.secret] No file found for secret '{secret_name}'! If it is a non-file secret, please use the 'secret' method.")
|
|
273
|
+
return None
|
|
274
|
+
|
|
275
|
+
except requests.exceptions.RequestException as e:
|
|
276
|
+
raise RuntimeError(f"[Dataflow.secret] Failed to fetch secret '{secret_name}'") from e
|
|
277
|
+
except Exception as e:
|
|
278
|
+
print(f"[Dataflow.secret] Exception occurred: {e}")
|
|
279
|
+
return None
|
|
180
280
|
|
|
181
281
|
def connection(self, conn_id: str, mode="session"):
|
|
182
282
|
"""
|
dataflow/environment.py
CHANGED
|
@@ -55,7 +55,8 @@ class EnvironmentManager:
|
|
|
55
55
|
status="published",
|
|
56
56
|
mode="create",
|
|
57
57
|
yaml_file_path=yaml_path,
|
|
58
|
-
version=int(env_version)
|
|
58
|
+
version=int(env_version),
|
|
59
|
+
py_version=py_version
|
|
59
60
|
)
|
|
60
61
|
elif status == "draft":
|
|
61
62
|
mode = "create" if env_version == '1' else "update"
|
|
@@ -65,7 +66,8 @@ class EnvironmentManager:
|
|
|
65
66
|
mode=mode,
|
|
66
67
|
yaml_file_path=yaml_path,
|
|
67
68
|
log_file_location=log_file_location,
|
|
68
|
-
version=int(env_version)
|
|
69
|
+
version=int(env_version),
|
|
70
|
+
py_version=py_version
|
|
69
71
|
)
|
|
70
72
|
|
|
71
73
|
# Update job log status if db was provided
|
|
@@ -191,6 +193,7 @@ class EnvironmentManager:
|
|
|
191
193
|
version: int,
|
|
192
194
|
source_path=None,
|
|
193
195
|
log_file_location=None,
|
|
196
|
+
py_version=None
|
|
194
197
|
):
|
|
195
198
|
"""
|
|
196
199
|
Executes environment operations (create or clone).
|
|
@@ -222,7 +225,7 @@ class EnvironmentManager:
|
|
|
222
225
|
|
|
223
226
|
if mode == "create":
|
|
224
227
|
create_env_script_path = pkg_resources.resource_filename('dataflow', 'scripts/create_environment.sh')
|
|
225
|
-
command = ["bash", create_env_script_path, yaml_file_path, conda_env_path]
|
|
228
|
+
command = ["bash", create_env_script_path, yaml_file_path, conda_env_path, py_version]
|
|
226
229
|
|
|
227
230
|
elif mode == "update":
|
|
228
231
|
update_env_script_path = pkg_resources.resource_filename('dataflow', 'scripts/update_environment.sh')
|
|
@@ -4,6 +4,7 @@ set -e
|
|
|
4
4
|
source_env_name=$1
|
|
5
5
|
target_env_path=$2
|
|
6
6
|
yaml_file_path=$3
|
|
7
|
+
py_version=$4
|
|
7
8
|
|
|
8
9
|
# Extract just the env name (basename) from the target path
|
|
9
10
|
env_name=$(basename "$target_env_path")
|
|
@@ -12,6 +13,9 @@ env_name=$(basename "$target_env_path")
|
|
|
12
13
|
export CONDA_PKGS_DIRS="/dataflow/envs/cache/${env_name}"
|
|
13
14
|
mkdir -p "$CONDA_PKGS_DIRS"
|
|
14
15
|
|
|
16
|
+
export PIP_CONSTRAINT="/dataflow/setup/pip_constraints/py${py_version}-constraints.txt"
|
|
17
|
+
export NO_CONDA_PLUGIN_PIP_CONSTRAINT="true"
|
|
18
|
+
|
|
15
19
|
# 1. Cloning conda env
|
|
16
20
|
conda create --clone ${source_env_name} --prefix ${target_env_path} --yes
|
|
17
21
|
|
|
@@ -5,9 +5,9 @@ authenticator/dataflowsupersetauthenticator.py,sha256=NkAmDaIc-ui-qEolu4xz_UY7P_
|
|
|
5
5
|
dataflow/__init__.py,sha256=WTRg8HMpMWSgxYJ9ZGVldx4k07fAbta3mBmZ1hG9mWE,30
|
|
6
6
|
dataflow/configuration.py,sha256=7To6XwH1eESiYp39eqPcswXWwrdBUdPF6xN6WnazOF0,663
|
|
7
7
|
dataflow/database_manager.py,sha256=tJHMuOZ9Muskrh9t4uLRlTuFU0VkHAzoHlGP5DORIC4,899
|
|
8
|
-
dataflow/dataflow.py,sha256=
|
|
8
|
+
dataflow/dataflow.py,sha256=kUuGZ1zV-kiu4IVP7hTKrAmLt33nXni-ppAEDOUsmyc,17622
|
|
9
9
|
dataflow/db.py,sha256=73ojGqpCTRVTlPszD73Ozhjih_BI2KTHmazqxxL6iWk,3780
|
|
10
|
-
dataflow/environment.py,sha256=
|
|
10
|
+
dataflow/environment.py,sha256=xMHCSjUzpK3dGuPhQPG28lZKtNtXHD0s4wfQVy9yTNs,28944
|
|
11
11
|
dataflow/models/__init__.py,sha256=FHus-b2oTgLSJ9H7dOCNJ14XpjTzHARqK_Vwh8VhCtM,1178
|
|
12
12
|
dataflow/models/app_types.py,sha256=BNGtjwpQU6MSpBGp0pDzUI4uDZNqvE3_x33itIInasM,689
|
|
13
13
|
dataflow/models/blacklist_library.py,sha256=B2oi3Z8GcR_glhLAyinFk0W8c9txXvm3uOER6dY-q7I,991
|
|
@@ -37,7 +37,7 @@ dataflow/schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
|
|
|
37
37
|
dataflow/schemas/connection.py,sha256=ut2sqz06yOjmFKzHry92FEt7DN09Bj30GYse35__Cuw,2467
|
|
38
38
|
dataflow/schemas/git_ssh.py,sha256=N1O7HM6ZbygIBZn2rKvNR0e7IM3ZJMAH6aJtjaghDr0,1283
|
|
39
39
|
dataflow/schemas/secret.py,sha256=wMSCn6zoBHS-R4NoKwljq2JUad8p9JY542UNJFa86X8,1183
|
|
40
|
-
dataflow/scripts/clone_environment.sh,sha256=
|
|
40
|
+
dataflow/scripts/clone_environment.sh,sha256=KHz29m_lN0SJeCTzd7-vmdmS7-aiM8KogduKp2Ttw8s,654
|
|
41
41
|
dataflow/scripts/create_environment.sh,sha256=3FHgNplJuEZvyTsLqlCJNX9oyfXgsfqn80VZk2xtvso,828
|
|
42
42
|
dataflow/scripts/update_environment.sh,sha256=2dtn2xlNi6frpig-sqlGE1_IKRbbkqYOCpf_qyMKKII,992
|
|
43
43
|
dataflow/secrets_manager/__init__.py,sha256=idGqIDtYl0De2WIK9Obl-N7SDPSYtVM0D-wXfZjCiy4,559
|
|
@@ -56,8 +56,8 @@ dfmigration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
56
56
|
dfmigration/env.py,sha256=w_3Kzr3LJCU5l1zBGsNcoNGZyR8fZEtMRsxE-cEqfHQ,1110
|
|
57
57
|
dfmigration/versions/001_initial_baseline_migration.py,sha256=lxjs7LZLs9-c7FQj7t7t49EOfLPPHMLI6iNp0PIBMRA,299
|
|
58
58
|
dfmigration/versions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
59
|
-
dataflow_core-2.1.
|
|
60
|
-
dataflow_core-2.1.
|
|
61
|
-
dataflow_core-2.1.
|
|
62
|
-
dataflow_core-2.1.
|
|
63
|
-
dataflow_core-2.1.
|
|
59
|
+
dataflow_core-2.1.16.dist-info/METADATA,sha256=vu039NfRwGVU7aR0TnR5Yk8Hzfzy-cW6Hul9nAN2xuU,463
|
|
60
|
+
dataflow_core-2.1.16.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
61
|
+
dataflow_core-2.1.16.dist-info/entry_points.txt,sha256=ppj_EIbYrJJwCPg1kfdsZk5q1N-Ejfis1neYrnjhO8o,117
|
|
62
|
+
dataflow_core-2.1.16.dist-info/top_level.txt,sha256=-gGoIBh-bUMtzOdna2jsDOdkE2CRu3w3aA7yEFCmNAI,35
|
|
63
|
+
dataflow_core-2.1.16.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|