fred-oss 0.56.0__tar.gz → 0.58.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.
- {fred_oss-0.56.0/src/main/fred_oss.egg-info → fred_oss-0.58.0}/PKG-INFO +1 -1
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/comp/_keyval.py +18 -7
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/_minio/service.py +11 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/rest/router/endpoint.py +5 -2
- fred_oss-0.58.0/src/main/fred/version +1 -0
- fred_oss-0.58.0/src/main/fred/worker/runner/rest/router/_base.py +22 -0
- {fred_oss-0.56.0/src/main/fred/worker/runner/rest/routers → fred_oss-0.58.0/src/main/fred/worker/runner/rest/router}/_runner.py +51 -62
- fred_oss-0.58.0/src/main/fred/worker/runner/rest/router/catalog.py +11 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0/src/main/fred_oss.egg-info}/PKG-INFO +1 -1
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred_oss.egg-info/SOURCES.txt +4 -8
- fred_oss-0.56.0/src/main/fred/version +0 -1
- fred_oss-0.56.0/src/main/fred/worker/runner/rest/auth.py +0 -22
- fred_oss-0.56.0/src/main/fred/worker/runner/rest/cli_ext.py +0 -32
- fred_oss-0.56.0/src/main/fred/worker/runner/rest/routers/catalog.py +0 -18
- fred_oss-0.56.0/src/main/fred/worker/runner/rest/routers/interface.py +0 -59
- fred_oss-0.56.0/src/main/fred/worker/runner/rest/server.py +0 -85
- fred_oss-0.56.0/src/main/fred/worker/runner/rest/settings.py +0 -21
- {fred_oss-0.56.0 → fred_oss-0.58.0}/MANIFEST.in +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/NOTICE.txt +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/README.md +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/requirements.txt +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/setup.cfg +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/setup.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/cli/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/cli/__main__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/cli/interface.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/cli/main.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/comp/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/comp/_pubsub.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/comp/_queue.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/comp/catalog.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/comp/interface.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/_minio/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/_minio/policy/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/_minio/policy/builder.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/_minio/policy/catalog.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/_minio/policy/loader.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/_minio/policy/templates/public_ro.json +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/_minio/policy/templates/public_rw.json +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/_minio/pool.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/_redis.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/_stdlib.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/catalog.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/interface.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/utils.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/future/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/future/callback/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/future/callback/_function.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/future/callback/catalog.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/future/callback/interface.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/future/impl.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/future/result.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/future/settings.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/future/utils.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/databricks/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/databricks/cli_ext.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/databricks/runtime.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/databricks/runtimes/16.4LTS.json +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/databricks/runtimes/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/databricks/runtimes/scanner.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/databricks/runtimes/sync.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/databricks/wrappers/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/databricks/wrappers/dbutils.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/runpod/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/runpod/cli_ext.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/runpod/helper.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/maturity.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/monad/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/monad/_either.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/monad/catalog.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/monad/interface.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/rest/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/rest/auth.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/rest/config.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/rest/router/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/rest/router/catalog/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/rest/router/catalog/default/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/rest/router/catalog/default/_base.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/rest/router/catalog/default/_example.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/rest/router/catalog/default/catalog.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/rest/router/catalog/interface.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/rest/router/config.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/rest/router/interface.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/rest/server.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/rest/settings.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/settings.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/utils/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/utils/dateops.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/utils/imops.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/utils/imout/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/utils/imout/_filesystem.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/utils/imout/_minio.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/utils/imout/_string.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/utils/imout/catalog.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/utils/imout/interface.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/utils/mlops/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/utils/mlops/auto.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/utils/runtime.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/version.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/interface.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/backend.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/client.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/handler.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/model/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/model/_handler.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/model/_item.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/model/_request.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/model/_runner_spec.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/model/catalog.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/model/interface.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/plugins/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/plugins/_local.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/plugins/_runpod.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/plugins/catalog.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/plugins/interface.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/rest/__init__.py +0 -0
- {fred_oss-0.56.0/src/main/fred/worker/runner/rest/routers → fred_oss-0.58.0/src/main/fred/worker/runner/rest/router}/__init__.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/settings.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/signal.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/status.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/runner/utils.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/worker/settings.py +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred_oss.egg-info/dependency_links.txt +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred_oss.egg-info/entry_points.txt +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred_oss.egg-info/requires.txt +0 -0
- {fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred_oss.egg-info/top_level.txt +0 -0
|
@@ -136,7 +136,7 @@ class FredKeyVal(ComponentInterface):
|
|
|
136
136
|
case _:
|
|
137
137
|
raise NotImplementedError(f"Set method not implemented for service {self._nme}")
|
|
138
138
|
|
|
139
|
-
def get(self, key: Optional[str] = None, fail: bool = False) -> Optional[str]:
|
|
139
|
+
def get(self, key: Optional[str] = None, fail: bool = False, **kwargs) -> Optional[str]:
|
|
140
140
|
"""Gets the value associated with a key from the store.
|
|
141
141
|
The implementation of this method depends on the underlying service.
|
|
142
142
|
For example, if the service is Redis, it uses the GET command to retrieve the
|
|
@@ -173,21 +173,32 @@ class FredKeyVal(ComponentInterface):
|
|
|
173
173
|
raise KeyError(f"Object {object_name} not found in bucket {bucket_name}.")
|
|
174
174
|
return None
|
|
175
175
|
try:
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
176
|
+
if kwargs.pop("presigned_url", False):
|
|
177
|
+
result = self._srv.object_presigned_url(bucket_name, object_name, **kwargs)
|
|
178
|
+
else:
|
|
179
|
+
response = self._srv.client.get_object(bucket_name, object_name)
|
|
180
|
+
result_bytes = response.read()
|
|
181
|
+
try:
|
|
182
|
+
# This should work for most cases where original text data was stored (e.g., JSON, YAML, CSVs, etc.)
|
|
183
|
+
result = result_bytes.decode("utf-8")
|
|
184
|
+
except UnicodeDecodeError:
|
|
185
|
+
import base64
|
|
186
|
+
# This should work for binary data (e.g., images, PDFs, etc.)
|
|
187
|
+
result = base64.b64encode(result_bytes).decode("ascii")
|
|
188
|
+
finally:
|
|
189
|
+
response.close()
|
|
190
|
+
response.release_conn()
|
|
179
191
|
except Exception as e:
|
|
180
192
|
logger.error(f"Error retrieving object {object_name} from bucket {bucket_name}: {e}")
|
|
181
193
|
result = None
|
|
182
194
|
if fail:
|
|
183
195
|
raise KeyError(f"Object {object_name} not found in bucket {bucket_name}.")
|
|
184
|
-
finally:
|
|
185
|
-
response.close()
|
|
186
|
-
response.release_conn()
|
|
187
196
|
case _:
|
|
188
197
|
raise NotImplementedError(f"Get method not implemented for service {self._nme}")
|
|
189
198
|
if fail and result is None:
|
|
190
199
|
raise KeyError(f"Key {key} not found.")
|
|
200
|
+
if kwargs:
|
|
201
|
+
logger.warning(f"Additional kwargs ignored: {kwargs}")
|
|
191
202
|
return result
|
|
192
203
|
|
|
193
204
|
def delete(self, key: Optional[str] = None) -> None:
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import datetime as dt
|
|
2
|
+
|
|
1
3
|
from minio import Minio
|
|
2
4
|
|
|
3
5
|
from fred.settings import logger_manager
|
|
@@ -62,6 +64,15 @@ class MinioService(ServiceInterface[Minio]):
|
|
|
62
64
|
"metadata": stat.metadata,
|
|
63
65
|
}
|
|
64
66
|
|
|
67
|
+
def object_presigned_url(self, bucket_name: str, object_name: str, expiration_hours: int = 6, **kwargs) -> str:
|
|
68
|
+
"""Generate a presigned URL for an object in a specific bucket in the MinIO instance."""
|
|
69
|
+
return self.client.presigned_get_object(
|
|
70
|
+
bucket_name=bucket_name,
|
|
71
|
+
object_name=object_name,
|
|
72
|
+
expires=dt.timedelta(hours=expiration_hours),
|
|
73
|
+
**kwargs,
|
|
74
|
+
)
|
|
75
|
+
|
|
65
76
|
def object_exists(self, bucket_name: str, object_name: str) -> bool:
|
|
66
77
|
"""Check if an object exists in a specific bucket in the MinIO instance."""
|
|
67
78
|
from minio.error import S3Error
|
|
@@ -62,7 +62,7 @@ class RouterEndpointAnnotation(RouterEndpoint):
|
|
|
62
62
|
config = RouterEndpointConfig.auto(**kwargs)
|
|
63
63
|
return lambda function: cls(function=function, configs=config)
|
|
64
64
|
|
|
65
|
-
def __get__(self,
|
|
65
|
+
def __get__(self, other_instance, other_class) -> RouterEndpoint:
|
|
66
66
|
# Create a partial function that binds the instance (other) to the method.
|
|
67
67
|
# This method was originally implemented using the following approaches:
|
|
68
68
|
# - function = functools.partial(self.function, other)
|
|
@@ -87,7 +87,10 @@ class RouterEndpointAnnotation(RouterEndpoint):
|
|
|
87
87
|
params.update(await request.json())
|
|
88
88
|
except Exception:
|
|
89
89
|
pass
|
|
90
|
-
|
|
90
|
+
# Since the annotation is usually applied to methods within a class,
|
|
91
|
+
# in most cases the 'other_instance' will be 'None'; therefore using 'other_class'
|
|
92
|
+
# should allow accessing the shared-class level state (e.g., runner_backend).
|
|
93
|
+
return self.function(other_class, **params)
|
|
91
94
|
return RouterEndpoint(
|
|
92
95
|
function=closure,
|
|
93
96
|
configs=self.configs
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.58.0
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from fred.rest.router.interface import RouterInterfaceMixin
|
|
4
|
+
from fred.rest.router.endpoint import RouterEndpointAnnotation
|
|
5
|
+
|
|
6
|
+
@dataclass(frozen=True, slots=True)
|
|
7
|
+
class RouterBaseMixin(RouterInterfaceMixin):
|
|
8
|
+
|
|
9
|
+
@RouterEndpointAnnotation.set(
|
|
10
|
+
path="/",
|
|
11
|
+
methods=["GET"],
|
|
12
|
+
summary="Base endpoint",
|
|
13
|
+
description="A simple base endpoint to check service availability."
|
|
14
|
+
)
|
|
15
|
+
def base(self, include_telemetry: bool = False, **kwargs) -> dict:
|
|
16
|
+
if include_telemetry:
|
|
17
|
+
from fred.utils.runtime import RuntimeProfilingSnapshot
|
|
18
|
+
kwargs["telemetry"] = RuntimeProfilingSnapshot.auto().to_dict()
|
|
19
|
+
return {
|
|
20
|
+
"ok": True,
|
|
21
|
+
**kwargs
|
|
22
|
+
}
|
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
1
|
from typing import Optional
|
|
3
2
|
|
|
4
3
|
from fred.future import Future
|
|
5
4
|
from fred.settings import logger_manager
|
|
6
5
|
from fred.utils.dateops import datetime_utcnow
|
|
7
|
-
from fred.
|
|
6
|
+
from fred.rest.router.interface import RouterInterfaceMixin
|
|
7
|
+
from fred.rest.router.endpoint import RouterEndpointAnnotation
|
|
8
8
|
|
|
9
9
|
logger = logger_manager.get_logger(name=__name__)
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
class
|
|
12
|
+
class RunnerRouterMixin(RouterInterfaceMixin):
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
@RouterEndpointAnnotation.set(
|
|
15
|
+
path="/handler_exists",
|
|
16
|
+
methods=["GET"],
|
|
17
|
+
tags=["Runner"],
|
|
18
|
+
summary="Check if a handler class exists and is a RunnerHandler.",
|
|
19
|
+
response_description="Details about the handler class.",
|
|
20
|
+
)
|
|
21
|
+
def handler_exists(self, classname: str, classpath: str, **kwargs) -> dict:
|
|
15
22
|
from fred.worker.runner.handler import RunnerHandler
|
|
16
23
|
from fred.worker.interface import HandlerInterface
|
|
17
24
|
|
|
@@ -35,8 +42,15 @@ class RunnerRouterMethods:
|
|
|
35
42
|
result_payload["metadata"]["error"] = str(e)
|
|
36
43
|
return result_payload
|
|
37
44
|
|
|
38
|
-
def qlen(self, queue_slug: str) -> dict:
|
|
39
45
|
|
|
46
|
+
@RouterEndpointAnnotation.set(
|
|
47
|
+
path="/qlen/{queue_slug}",
|
|
48
|
+
methods=["GET"],
|
|
49
|
+
tags=["Runner"],
|
|
50
|
+
summary="Get the length of the request and response queues for a given queue slug.",
|
|
51
|
+
response_description="The lengths of the request and response queues.",
|
|
52
|
+
)
|
|
53
|
+
def qlen(self, queue_slug: str, **kwargs) -> dict:
|
|
40
54
|
snapshot_at = datetime_utcnow().isoformat()
|
|
41
55
|
req_queue = self.runner_backend.queue(f"req:{queue_slug}")
|
|
42
56
|
res_queue = self.runner_backend.queue(f"res:{queue_slug}")
|
|
@@ -49,34 +63,48 @@ class RunnerRouterMethods:
|
|
|
49
63
|
"res": res_queue.size(),
|
|
50
64
|
}
|
|
51
65
|
|
|
52
|
-
|
|
66
|
+
@RouterEndpointAnnotation.set(
|
|
67
|
+
path="/start",
|
|
68
|
+
methods=["POST"],
|
|
69
|
+
tags=["Runner"],
|
|
70
|
+
summary="Start a runner using the specified plugin.",
|
|
71
|
+
response_description="The ID of the started runner.",
|
|
72
|
+
)
|
|
73
|
+
def runner_start(self, **kwargs) -> dict:
|
|
53
74
|
from fred.worker.runner.model.catalog import RunnerModelCatalog
|
|
54
75
|
from fred.worker.runner.plugins.catalog import PluginCatalog
|
|
55
76
|
# Determine which plugin to use; default to LOCAL if not specified
|
|
56
|
-
plugin_name: str =
|
|
57
|
-
wait_for_exec: bool =
|
|
77
|
+
plugin_name: str = kwargs.pop("plugin", "LOCAL")
|
|
78
|
+
wait_for_exec: bool = kwargs.pop("wait_for_exec", False)
|
|
58
79
|
# Create the RunnerSpec from the provided payload
|
|
59
80
|
# TODO: Instead on depending on parsing a dict... Can we implement a base-model to facilitate fast-api validation?
|
|
60
|
-
runner_spec = RunnerModelCatalog.RUNNER_SPEC.value.from_payload(payload=
|
|
81
|
+
runner_spec = RunnerModelCatalog.RUNNER_SPEC.value.from_payload(payload=kwargs)
|
|
61
82
|
# Instantiate the plugin and execute the runner
|
|
62
83
|
plugin = PluginCatalog[plugin_name.upper()]()
|
|
63
|
-
output = plugin.execute(runner_spec, wait_for_exec=wait_for_exec, **
|
|
84
|
+
output = plugin.execute(runner_spec, wait_for_exec=wait_for_exec, **kwargs)
|
|
64
85
|
return {
|
|
65
86
|
"runner_id": output.runner_id,
|
|
66
87
|
"future_id": output.future_exec.future_id,
|
|
67
88
|
"queue_slug": runner_spec.queue_slug,
|
|
68
89
|
}
|
|
69
|
-
|
|
70
|
-
|
|
90
|
+
|
|
91
|
+
@RouterEndpointAnnotation.set(
|
|
92
|
+
path="/execute",
|
|
93
|
+
methods=["POST"],
|
|
94
|
+
tags=["Runner"],
|
|
95
|
+
summary="Execute a task by dispatching a request to the specified queue.",
|
|
96
|
+
response_description="Details about the dispatched request.",
|
|
97
|
+
)
|
|
98
|
+
def runner_execute(self, **kwargs) -> dict:
|
|
71
99
|
from fred.worker.runner.model.catalog import RunnerModelCatalog
|
|
72
100
|
|
|
73
|
-
request_id =
|
|
74
|
-
queue_slug =
|
|
101
|
+
request_id = kwargs.pop("request_id", None)
|
|
102
|
+
queue_slug = kwargs.pop("queue_slug", None) or (
|
|
75
103
|
logger.error("No 'queue_slug' value provided; defaulting to 'demo'.")
|
|
76
104
|
or "demo"
|
|
77
105
|
)
|
|
78
106
|
|
|
79
|
-
item = RunnerModelCatalog.ITEM.value.uuid(payload=
|
|
107
|
+
item = RunnerModelCatalog.ITEM.value.uuid(payload=kwargs, uuid_hash=False)
|
|
80
108
|
request = item.as_request(use_hash=False, request_id=request_id)
|
|
81
109
|
request.dispatch(
|
|
82
110
|
request_queue=self.runner_backend.queue(f"req:{queue_slug}")
|
|
@@ -88,7 +116,14 @@ class RunnerRouterMethods:
|
|
|
88
116
|
"dispatched_at": datetime_utcnow().isoformat(),
|
|
89
117
|
}
|
|
90
118
|
|
|
91
|
-
|
|
119
|
+
@RouterEndpointAnnotation.set(
|
|
120
|
+
path="/output/{request_id}",
|
|
121
|
+
methods=["GET"],
|
|
122
|
+
tags=["Runner"],
|
|
123
|
+
summary="Fetch the output of a previously dispatched request.",
|
|
124
|
+
response_description="The output of the request.",
|
|
125
|
+
)
|
|
126
|
+
def runner_output(self, request_id: str, nonblocking: bool = False, timeout: Optional[float] = None, **kwargs) -> dict:
|
|
92
127
|
|
|
93
128
|
output_requested_at = datetime_utcnow().isoformat()
|
|
94
129
|
# Subscribe to the future result using the request_id
|
|
@@ -102,49 +137,3 @@ class RunnerRouterMethods:
|
|
|
102
137
|
"output_delivered_at": datetime_utcnow().isoformat(),
|
|
103
138
|
"output": future.wait_and_resolve(timeout=timeout),
|
|
104
139
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
@dataclass(frozen=True, slots=False)
|
|
108
|
-
class RunnerRouter(RouterInterface.with_backend(), RunnerRouterMethods):
|
|
109
|
-
|
|
110
|
-
def __post_init__(self):
|
|
111
|
-
self.router.add_api_route(
|
|
112
|
-
"/handler_exists",
|
|
113
|
-
self.handler_exists,
|
|
114
|
-
methods=["GET"],
|
|
115
|
-
tags=["Runner"],
|
|
116
|
-
summary="Check if a handler class exists and is a RunnerHandler.",
|
|
117
|
-
response_description="Details about the handler class.",
|
|
118
|
-
)
|
|
119
|
-
self.router.add_api_route(
|
|
120
|
-
"/qlen/{queue_slug}",
|
|
121
|
-
self.qlen,
|
|
122
|
-
methods=["GET"],
|
|
123
|
-
tags=["Runner"],
|
|
124
|
-
summary="Get the length of the request and response queues for a given queue slug.",
|
|
125
|
-
response_description="The lengths of the request and response queues.",
|
|
126
|
-
)
|
|
127
|
-
self.router.add_api_route(
|
|
128
|
-
"/start",
|
|
129
|
-
self.runner_start,
|
|
130
|
-
methods=["POST"],
|
|
131
|
-
tags=["Runner"],
|
|
132
|
-
summary="Start a runner using the specified plugin.",
|
|
133
|
-
response_description="The ID of the started runner.",
|
|
134
|
-
)
|
|
135
|
-
self.router.add_api_route(
|
|
136
|
-
"/execute",
|
|
137
|
-
self.runner_execute,
|
|
138
|
-
methods=["POST"],
|
|
139
|
-
tags=["Runner"],
|
|
140
|
-
summary="Execute a task by dispatching a request to the specified queue.",
|
|
141
|
-
response_description="Details about the dispatched request.",
|
|
142
|
-
)
|
|
143
|
-
self.router.add_api_route(
|
|
144
|
-
"/output/{request_id}",
|
|
145
|
-
self.runner_output,
|
|
146
|
-
methods=["GET"],
|
|
147
|
-
tags=["Runner"],
|
|
148
|
-
summary="Fetch the output of a previously dispatched request.",
|
|
149
|
-
response_description="The output of the request.",
|
|
150
|
-
)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import enum
|
|
2
|
+
|
|
3
|
+
from fred.rest.router.config import RouterConfig
|
|
4
|
+
from fred.rest.router.catalog.interface import RouterCatalogInterface
|
|
5
|
+
from fred.worker.runner.rest.router._runner import RunnerRouterMixin
|
|
6
|
+
from fred.worker.runner.rest.router._base import RouterBaseMixin
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class RouterCatalog(RouterCatalogInterface, enum.Enum):
|
|
10
|
+
BASE = RouterConfig.auto(prefix="")(apply=RouterBaseMixin)
|
|
11
|
+
RUNNER = RouterConfig.auto(prefix="/runner", tags=["Runner"])(apply=RunnerRouterMixin)
|
|
@@ -109,14 +109,10 @@ src/main/fred/worker/runner/plugins/_runpod.py
|
|
|
109
109
|
src/main/fred/worker/runner/plugins/catalog.py
|
|
110
110
|
src/main/fred/worker/runner/plugins/interface.py
|
|
111
111
|
src/main/fred/worker/runner/rest/__init__.py
|
|
112
|
-
src/main/fred/worker/runner/rest/
|
|
113
|
-
src/main/fred/worker/runner/rest/
|
|
114
|
-
src/main/fred/worker/runner/rest/
|
|
115
|
-
src/main/fred/worker/runner/rest/
|
|
116
|
-
src/main/fred/worker/runner/rest/routers/__init__.py
|
|
117
|
-
src/main/fred/worker/runner/rest/routers/_runner.py
|
|
118
|
-
src/main/fred/worker/runner/rest/routers/catalog.py
|
|
119
|
-
src/main/fred/worker/runner/rest/routers/interface.py
|
|
112
|
+
src/main/fred/worker/runner/rest/router/__init__.py
|
|
113
|
+
src/main/fred/worker/runner/rest/router/_base.py
|
|
114
|
+
src/main/fred/worker/runner/rest/router/_runner.py
|
|
115
|
+
src/main/fred/worker/runner/rest/router/catalog.py
|
|
120
116
|
src/main/fred_oss.egg-info/PKG-INFO
|
|
121
117
|
src/main/fred_oss.egg-info/SOURCES.txt
|
|
122
118
|
src/main/fred_oss.egg-info/dependency_links.txt
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.56.0
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
from fastapi import Security, HTTPException, status
|
|
2
|
-
from fastapi.security import APIKeyHeader
|
|
3
|
-
|
|
4
|
-
from fred.worker.runner.rest.settings import FRD_RESTAPI_TOKEN
|
|
5
|
-
|
|
6
|
-
async def verify_key(
|
|
7
|
-
api_key_header: str = Security(
|
|
8
|
-
APIKeyHeader(
|
|
9
|
-
name="X-API-Key",
|
|
10
|
-
auto_error=False
|
|
11
|
-
)
|
|
12
|
-
),
|
|
13
|
-
):
|
|
14
|
-
"""
|
|
15
|
-
Verify the provided API key against the expected token.
|
|
16
|
-
Raises an HTTPException if the key is invalid or missing.
|
|
17
|
-
"""
|
|
18
|
-
if api_key_header != FRD_RESTAPI_TOKEN:
|
|
19
|
-
raise HTTPException(
|
|
20
|
-
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
21
|
-
detail="Invalid or missing API Key",
|
|
22
|
-
)
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
from typing import Optional
|
|
2
|
-
|
|
3
|
-
from fred.cli.interface import IntegrationExtCLI
|
|
4
|
-
from fred.settings import logger_manager
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
logger = logger_manager.get_logger(name=__name__)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class RunnerServerExt(IntegrationExtCLI):
|
|
11
|
-
|
|
12
|
-
def start(
|
|
13
|
-
self,
|
|
14
|
-
include_routers: Optional[list[str]] = None,
|
|
15
|
-
exclude_routers: Optional[list[str]] = None,
|
|
16
|
-
fast_api_configs: Optional[dict] = None,
|
|
17
|
-
server_configs: Optional[dict] = None,
|
|
18
|
-
):
|
|
19
|
-
from fred.worker.runner.rest.server import RunnerServer
|
|
20
|
-
|
|
21
|
-
include_routers = include_routers or []
|
|
22
|
-
exclude_routers = exclude_routers or []
|
|
23
|
-
fast_api_configs = fast_api_configs or {}
|
|
24
|
-
server_configs = server_configs or {}
|
|
25
|
-
|
|
26
|
-
logger.info("Starting REST server...")
|
|
27
|
-
server = RunnerServer.auto(
|
|
28
|
-
include_routers=include_routers,
|
|
29
|
-
exclude_routers=exclude_routers,
|
|
30
|
-
**fast_api_configs,
|
|
31
|
-
)
|
|
32
|
-
server.start(**server_configs)
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import enum
|
|
2
|
-
|
|
3
|
-
from fred.worker.runner.rest.routers.interface import RouterInterface
|
|
4
|
-
from fred.worker.runner.rest.routers._runner import RunnerRouter
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class RouterCatalog(enum.Enum):
|
|
8
|
-
EXAMPLE = RouterInterface.auto() # Default example router directly from the base interface
|
|
9
|
-
RUNNER = RunnerRouter.auto(
|
|
10
|
-
prefix="/runner",
|
|
11
|
-
tags=["Runner"],
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
def get_router_instance(self) -> RouterInterface:
|
|
15
|
-
return self.value.router
|
|
16
|
-
|
|
17
|
-
def get_router_configs(self) -> dict:
|
|
18
|
-
return self.value.router_configs
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from typing import Optional
|
|
3
|
-
|
|
4
|
-
from fred.worker.runner.backend import RunnerBackend
|
|
5
|
-
from fred.worker.runner.settings import FRD_RUNNER_BACKEND
|
|
6
|
-
|
|
7
|
-
from fastapi import APIRouter
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class RouterInterfaceBackendMixin:
|
|
11
|
-
"""Base class for router interfaces that require a backend service."""
|
|
12
|
-
runner_backend: RunnerBackend
|
|
13
|
-
|
|
14
|
-
@classmethod
|
|
15
|
-
def with_backend(cls, service_name: Optional[str] = None, **kwargs) -> type["RouterInterfaceBackendMixin"]:
|
|
16
|
-
# Avoid re-initializing if already set
|
|
17
|
-
if getattr(cls, "runner_backend", None):
|
|
18
|
-
return cls
|
|
19
|
-
# Initialize the backend once and assign to the class attribute
|
|
20
|
-
cls.runner_backend = RunnerBackend.auto(
|
|
21
|
-
service_name=service_name or FRD_RUNNER_BACKEND,
|
|
22
|
-
**kwargs,
|
|
23
|
-
)
|
|
24
|
-
return cls
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
@dataclass(frozen=True, slots=False)
|
|
28
|
-
class RouterInterface(RouterInterfaceBackendMixin):
|
|
29
|
-
router: APIRouter
|
|
30
|
-
router_configs: dict
|
|
31
|
-
|
|
32
|
-
@classmethod
|
|
33
|
-
def auto(
|
|
34
|
-
cls,
|
|
35
|
-
router: Optional[APIRouter] = None,
|
|
36
|
-
**kwargs,
|
|
37
|
-
) -> "RouterInterface":
|
|
38
|
-
return cls(
|
|
39
|
-
router=router or APIRouter(),
|
|
40
|
-
router_configs=kwargs,
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
def __post_init__(self):
|
|
44
|
-
self.router.add_api_route(
|
|
45
|
-
"/ping",
|
|
46
|
-
self.ping,
|
|
47
|
-
methods=["GET"],
|
|
48
|
-
tags=["Health"],
|
|
49
|
-
summary="Ping the server to check if it's alive.",
|
|
50
|
-
response_description="A simple pong response.",
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
def ping(self, pong: Optional[str] = None) -> dict:
|
|
54
|
-
from fred.utils.dateops import datetime_utcnow
|
|
55
|
-
|
|
56
|
-
return {
|
|
57
|
-
"ping_time": datetime_utcnow().isoformat(),
|
|
58
|
-
"ping_response": pong or "pong",
|
|
59
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
|
|
3
|
-
from fastapi import FastAPI, Depends
|
|
4
|
-
|
|
5
|
-
from fred.settings import logger_manager, get_environ_variable
|
|
6
|
-
from fred.worker.runner.rest.settings import (
|
|
7
|
-
FRD_RESTAPI_HOST,
|
|
8
|
-
FRD_RESTAPI_PORT,
|
|
9
|
-
)
|
|
10
|
-
from fred.worker.runner.rest.routers.catalog import RouterCatalog
|
|
11
|
-
from fred.worker.runner.rest.auth import verify_key
|
|
12
|
-
|
|
13
|
-
logger = logger_manager.get_logger(name=__name__)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@dataclass(frozen=True, slots=True)
|
|
17
|
-
class RunnerServer:
|
|
18
|
-
app: FastAPI
|
|
19
|
-
include_routers: list[str]
|
|
20
|
-
exclude_routers: list[str]
|
|
21
|
-
|
|
22
|
-
@classmethod
|
|
23
|
-
def auto(cls, **kwargs) -> "RunnerServer":
|
|
24
|
-
# Include routers by checking on keyword argument or environment variable
|
|
25
|
-
include_routers = kwargs.pop("include_routers", None) or get_environ_variable(
|
|
26
|
-
"FRD_RUNNER_API_INCLUDE_ROUTERS",
|
|
27
|
-
default=""
|
|
28
|
-
)
|
|
29
|
-
if isinstance(include_routers, str):
|
|
30
|
-
include_routers = [
|
|
31
|
-
name.upper()
|
|
32
|
-
for router in include_routers.split(";")
|
|
33
|
-
if (name := router.strip())
|
|
34
|
-
]
|
|
35
|
-
# Exclude routers by checking on keyword argument or environment variable
|
|
36
|
-
exclude_routers = kwargs.pop("exclude_routers", None) or get_environ_variable(
|
|
37
|
-
"FRD_RUNNER_API_EXCLUDE_ROUTERS",
|
|
38
|
-
default=""
|
|
39
|
-
)
|
|
40
|
-
if isinstance(exclude_routers, str):
|
|
41
|
-
exclude_routers = [
|
|
42
|
-
name.upper()
|
|
43
|
-
for router in exclude_routers.split(";")
|
|
44
|
-
if (name := router.strip())
|
|
45
|
-
]
|
|
46
|
-
# Create FastAPI instance
|
|
47
|
-
kwargs["dependencies"] = kwargs.get("dependencies", []) + [
|
|
48
|
-
Depends(verify_key),
|
|
49
|
-
]
|
|
50
|
-
app_instance = FastAPI(**kwargs)
|
|
51
|
-
return cls(
|
|
52
|
-
app=app_instance,
|
|
53
|
-
include_routers=include_routers,
|
|
54
|
-
exclude_routers=exclude_routers,
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
def __post_init__(self):
|
|
58
|
-
logger.info("Attempting to register routers...")
|
|
59
|
-
logger.info("Included routers candidates: %s", self.include_routers or "ALL")
|
|
60
|
-
logger.info("Excluded routers candidates: %s", self.exclude_routers or "NONE")
|
|
61
|
-
for router in RouterCatalog:
|
|
62
|
-
name = router.name.upper()
|
|
63
|
-
if self.include_routers and name not in self.include_routers:
|
|
64
|
-
logger.info(f"Skipping router '{name}' as it's not in the include list.")
|
|
65
|
-
continue
|
|
66
|
-
if self.exclude_routers and name in self.exclude_routers:
|
|
67
|
-
logger.info(f"Skipping router '{name}' as it's in the exclude list.")
|
|
68
|
-
continue
|
|
69
|
-
logger.info(f"Registering router '{name}'.")
|
|
70
|
-
self.app.include_router(
|
|
71
|
-
router.get_router_instance(),
|
|
72
|
-
**router.get_router_configs(),
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
def start(self, **kwargs):
|
|
76
|
-
import uvicorn
|
|
77
|
-
|
|
78
|
-
server_kwargs = {
|
|
79
|
-
"host": kwargs.pop("host", FRD_RESTAPI_HOST),
|
|
80
|
-
"port": int(kwargs.pop("port", FRD_RESTAPI_PORT)),
|
|
81
|
-
"log_level": "info",
|
|
82
|
-
**kwargs,
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
uvicorn.run(self.app, **server_kwargs)
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
from fred.settings import get_environ_variable, logger_manager
|
|
2
|
-
|
|
3
|
-
logger = logger_manager.get_logger(name=__name__)
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
FRD_RESTAPI_HOST = get_environ_variable(
|
|
7
|
-
"FRD_RESTAPI_HOST",
|
|
8
|
-
default="0.0.0.0"
|
|
9
|
-
)
|
|
10
|
-
FRD_RESTAPI_PORT = int(get_environ_variable(
|
|
11
|
-
"FRD_RESTAPI_PORT",
|
|
12
|
-
default=8000
|
|
13
|
-
))
|
|
14
|
-
|
|
15
|
-
FRD_RESTAPI_TOKEN = get_environ_variable(
|
|
16
|
-
"FRD_RESTAPI_TOKEN",
|
|
17
|
-
default=None
|
|
18
|
-
)
|
|
19
|
-
if not FRD_RESTAPI_TOKEN:
|
|
20
|
-
logger.warning("FRD_RESTAPI_TOKEN not found in environment; using default token 'changeme'.")
|
|
21
|
-
FRD_RESTAPI_TOKEN = "changeme"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/_minio/policy/templates/public_ro.json
RENAMED
|
File without changes
|
{fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/dao/service/_minio/policy/templates/public_rw.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/databricks/runtimes/16.4LTS.json
RENAMED
|
File without changes
|
{fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/databricks/runtimes/__init__.py
RENAMED
|
File without changes
|
{fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/databricks/runtimes/scanner.py
RENAMED
|
File without changes
|
|
File without changes
|
{fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/databricks/wrappers/__init__.py
RENAMED
|
File without changes
|
{fred_oss-0.56.0 → fred_oss-0.58.0}/src/main/fred/integrations/databricks/wrappers/dbutils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|