indexify 0.2.30__tar.gz → 0.2.32__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.
- {indexify-0.2.30 → indexify-0.2.32}/PKG-INFO +2 -2
- {indexify-0.2.30 → indexify-0.2.32}/indexify/executor/downloader.py +1 -1
- {indexify-0.2.30 → indexify-0.2.32}/indexify/functions_sdk/graph.py +37 -7
- {indexify-0.2.30 → indexify-0.2.32}/indexify/functions_sdk/indexify_functions.py +13 -9
- {indexify-0.2.30 → indexify-0.2.32}/indexify/remote_graph.py +1 -0
- {indexify-0.2.30 → indexify-0.2.32}/pyproject.toml +3 -7
- {indexify-0.2.30 → indexify-0.2.32}/LICENSE.txt +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/README.md +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/__init__.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/cli.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/common_util.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/data_loaders/__init__.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/data_loaders/local_directory_loader.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/data_loaders/url_loader.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/error.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/executor/agent.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/executor/api_objects.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/executor/executor_tasks.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/executor/function_worker.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/executor/image_dependency_installer.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/executor/indexify_executor.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/executor/runtime_probes.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/executor/task_reporter.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/executor/task_store.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/functions_sdk/data_objects.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/functions_sdk/graph_definition.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/functions_sdk/graph_validation.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/functions_sdk/image.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/functions_sdk/local_cache.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/functions_sdk/object_serializer.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/functions_sdk/pipeline.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/http_client.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/remote_pipeline.py +0 -0
- {indexify-0.2.30 → indexify-0.2.32}/indexify/settings.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: indexify
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.32
|
4
4
|
Summary: Python Client for Indexify
|
5
5
|
Home-page: https://github.com/tensorlakeai/indexify
|
6
6
|
License: Apache 2.0
|
@@ -20,7 +20,7 @@ Requires-Dist: httpx-sse (>=0.4.0,<0.5.0)
|
|
20
20
|
Requires-Dist: httpx[http2] (>=0,<1)
|
21
21
|
Requires-Dist: jsonpickle (>=4.0.0,<5.0.0)
|
22
22
|
Requires-Dist: nanoid (>=2.0.0,<3.0.0)
|
23
|
-
Requires-Dist: pydantic (
|
23
|
+
Requires-Dist: pydantic (==2.10.2)
|
24
24
|
Requires-Dist: pyyaml (>=6,<7)
|
25
25
|
Requires-Dist: rich (>=13.9.2,<14.0.0)
|
26
26
|
Requires-Dist: typer (>=0.13.0,<0.14.0)
|
@@ -120,7 +120,7 @@ class Downloader:
|
|
120
120
|
deserialized_content = serializer.deserialize(response.content)
|
121
121
|
|
122
122
|
if reducer_url:
|
123
|
-
init_value =
|
123
|
+
init_value = self._client.get(reducer_url)
|
124
124
|
try:
|
125
125
|
init_value.raise_for_status()
|
126
126
|
except httpx.HTTPStatusError as e:
|
@@ -101,9 +101,9 @@ class Graph:
|
|
101
101
|
return self
|
102
102
|
|
103
103
|
if issubclass(indexify_fn, IndexifyFunction) and indexify_fn.accumulate:
|
104
|
-
self.accumulator_zero_values[
|
105
|
-
indexify_fn.
|
106
|
-
|
104
|
+
self.accumulator_zero_values[indexify_fn.name] = (
|
105
|
+
indexify_fn.accumulate().model_dump()
|
106
|
+
)
|
107
107
|
|
108
108
|
self.nodes[indexify_fn.name] = indexify_fn
|
109
109
|
return self
|
@@ -210,6 +210,7 @@ class Graph:
|
|
210
210
|
)
|
211
211
|
|
212
212
|
def run(self, block_until_done: bool = False, **kwargs) -> str:
|
213
|
+
self.validate_graph()
|
213
214
|
start_node = self.nodes[self._start_node]
|
214
215
|
serializer = get_serializer(start_node.encoder)
|
215
216
|
input = IndexifyData(
|
@@ -236,6 +237,35 @@ class Graph:
|
|
236
237
|
self._run(input, outputs)
|
237
238
|
return input.id
|
238
239
|
|
240
|
+
def validate_graph(self) -> None:
|
241
|
+
"""
|
242
|
+
A method to validate that each node in the graph is
|
243
|
+
reachable from start node using BFS.
|
244
|
+
"""
|
245
|
+
total_number_of_nodes = len(self.nodes)
|
246
|
+
queue = deque([self._start_node])
|
247
|
+
visited = {self._start_node}
|
248
|
+
|
249
|
+
while queue:
|
250
|
+
current_node_name = queue.popleft()
|
251
|
+
neighbours = (
|
252
|
+
self.edges[current_node_name]
|
253
|
+
if self.edges[current_node_name]
|
254
|
+
else self.routers[current_node_name]
|
255
|
+
)
|
256
|
+
for neighbour in neighbours:
|
257
|
+
if neighbour in visited:
|
258
|
+
continue
|
259
|
+
else:
|
260
|
+
visited.add(neighbour)
|
261
|
+
queue.append(neighbour)
|
262
|
+
|
263
|
+
if total_number_of_nodes != len(visited):
|
264
|
+
# all the nodes are not reachable from the start_node.
|
265
|
+
raise Exception(
|
266
|
+
"Some nodes in the graph are not reachable from start node."
|
267
|
+
)
|
268
|
+
|
239
269
|
def _run(
|
240
270
|
self,
|
241
271
|
initial_input: IndexifyData,
|
@@ -244,9 +274,9 @@ class Graph:
|
|
244
274
|
queue = deque([(self._start_node, initial_input)])
|
245
275
|
while queue:
|
246
276
|
node_name, input = queue.popleft()
|
247
|
-
function_outputs: Union[
|
248
|
-
|
249
|
-
|
277
|
+
function_outputs: Union[FunctionCallResult, RouterCallResult] = (
|
278
|
+
self._invoke_fn(node_name, input)
|
279
|
+
)
|
250
280
|
self._log_local_exec_tracebacks(function_outputs)
|
251
281
|
if isinstance(function_outputs, RouterCallResult):
|
252
282
|
for edge in function_outputs.edges:
|
@@ -275,7 +305,7 @@ class Graph:
|
|
275
305
|
self, node_name: str, input: IndexifyData
|
276
306
|
) -> Optional[Union[RouterCallResult, FunctionCallResult]]:
|
277
307
|
node = self.nodes[node_name]
|
278
|
-
if node_name in self.routers:
|
308
|
+
if node_name in self.routers and len(self.routers[node_name]) > 0:
|
279
309
|
result = IndexifyFunctionWrapper(node, self._local_graph_ctx).invoke_router(
|
280
310
|
node_name, input
|
281
311
|
)
|
@@ -137,9 +137,11 @@ def indexify_router(
|
|
137
137
|
|
138
138
|
attrs = {
|
139
139
|
"name": name if name else fn.__name__,
|
140
|
-
"description":
|
141
|
-
|
142
|
-
|
140
|
+
"description": (
|
141
|
+
description
|
142
|
+
if description
|
143
|
+
else (fn.__doc__ or "").strip().replace("\n", "")
|
144
|
+
),
|
143
145
|
"image": image,
|
144
146
|
"placement_constraints": placement_constraints,
|
145
147
|
"encoder": encoder,
|
@@ -174,9 +176,11 @@ def indexify_function(
|
|
174
176
|
|
175
177
|
attrs = {
|
176
178
|
"name": name if name else fn.__name__,
|
177
|
-
"description":
|
178
|
-
|
179
|
-
|
179
|
+
"description": (
|
180
|
+
description
|
181
|
+
if description
|
182
|
+
else (fn.__doc__ or "").strip().replace("\n", "")
|
183
|
+
),
|
180
184
|
"image": image,
|
181
185
|
"placement_constraints": placement_constraints,
|
182
186
|
"accumulate": accumulate,
|
@@ -205,9 +209,9 @@ class IndexifyFunctionWrapper:
|
|
205
209
|
indexify_function: Union[IndexifyFunction, IndexifyRouter],
|
206
210
|
context: GraphInvocationContext,
|
207
211
|
):
|
208
|
-
self.indexify_function: Union[
|
209
|
-
|
210
|
-
|
212
|
+
self.indexify_function: Union[IndexifyFunction, IndexifyRouter] = (
|
213
|
+
indexify_function()
|
214
|
+
)
|
211
215
|
self.indexify_function._ctx = context
|
212
216
|
|
213
217
|
def get_output_model(self) -> Any:
|
@@ -90,6 +90,7 @@ class RemoteGraph:
|
|
90
90
|
:param client: The IndexifyClient used to communicate with the server.
|
91
91
|
Prefered over server_url.
|
92
92
|
"""
|
93
|
+
g.validate_graph()
|
93
94
|
if not client:
|
94
95
|
client = IndexifyClient(service_url=server_url)
|
95
96
|
client.register_compute_graph(g, additional_modules)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "indexify"
|
3
|
-
version = "0.2.
|
3
|
+
version = "0.2.32"
|
4
4
|
description = "Python Client for Indexify"
|
5
5
|
authors = ["Tensorlake Inc. <support@tensorlake.ai>"]
|
6
6
|
license = "Apache 2.0"
|
@@ -15,7 +15,7 @@ indexify-cli = "indexify.cli:app"
|
|
15
15
|
python = "^3.9"
|
16
16
|
httpx = { version = "^0", extras = ["http2"] }
|
17
17
|
pyyaml = "^6"
|
18
|
-
pydantic = "
|
18
|
+
pydantic = "2.10.2"
|
19
19
|
cloudpickle = "^3.1.0"
|
20
20
|
rich = "^13.9.2"
|
21
21
|
nanoid = "^2.0.0"
|
@@ -25,12 +25,8 @@ httpx-sse = "^0.4.0"
|
|
25
25
|
jsonpickle = "^4.0.0"
|
26
26
|
|
27
27
|
[tool.poetry.dev-dependencies]
|
28
|
-
black = "^
|
28
|
+
black = "^24.10.0"
|
29
29
|
pylint = "^2.4.0"
|
30
|
-
pytest = "^7.1.1"
|
31
|
-
pytest-cov = "^4.0.0"
|
32
|
-
pytest-runner = "^6.0.0"
|
33
|
-
pytest-watch = "^4.2.0"
|
34
30
|
parameterized = "^0.9.0"
|
35
31
|
|
36
32
|
[build-system]
|
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
|