Skip to content

Commit

Permalink
update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
diptanu committed Oct 3, 2024
1 parent 5a338ab commit 9172ea8
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 57 deletions.
43 changes: 21 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,37 +42,26 @@ class Total(BaseModel):
def generate_numbers(a: int) -> List[int]:
return [i for i in range(a)]

@indexify_function(accumulate=Total)
def add(total: Total, new: int) -> Total:
total.val += new
return total

@indexify_function()
def square(total: Total) -> int:
return total.val ** 2

@indexify_function()
def cube(total: Total) -> int:
return total.val ** 3

@indexify_router()
def dynamic_router(val: Total) -> List[Union[square, cube]]:
if val.val % 2:
return [square]
return [cube]
@indexify_function(accumulate=Total)
def add(total: Total, new: int) -> Total:
total.val += new
return total

g = Graph(name="sequence_summer", start_node=generate_numbers, description="Simple Sequence Summer")
g.add_edge(generate_numbers, add)
g.add_edge(add, dynamic_router)
g.route(dynamic_router, [square, cube])
g.add_edge(generate_numbers, square)
g.add_edge(square, add)
```

You can separate heavy tasks like local inference of LLMs from database write operations to prevent reprocessing data if a write fails. Indexify caches each function's output, so when you retry downstream processes, previous steps aren't repeated.

#### 2: Test the Graph In-Process
```python
invocation_id = g.run(a=10)
result = g.get_outputs(invocation_id, "squared")
result = g.get_output(invocation_id, "add")
print(result)
```

Expand All @@ -99,16 +88,26 @@ Change the code above to deploy the graph as an API -
```python
from indexify import RemoteGraph

graph = RemoteGraph.new(g)
graph = RemoteGraph.deploy(g)
invocation_id = graph.run(block_until_done=True, a=10)
result = graph.get_outputs(invocation_id, "squared")
result = graph.get_output(invocation_id, "add")
print(result)
```

This serializes your Graph code and uploads it to the server, and instantiates a new endpoint.
Everything else, remains the same in your application code that invokes the Graph to process data and retrieve outputs!

#### 4: Deploying Graph Endpoints using Docker Compose
#### 4: Call Remote Graphs from Applications

You can call these remote graphs from any application. Think about them like an extension of your application.

```python
graph = RemoteGraph.by_name("sequence_summer")
invocation_id = graph.run(block_until_done=True, a=5)
print(graph.get_output(invocation_id, "add"))
```

#### 5: Deploying Graph Endpoints using Docker Compose
You can spin up the server and executor using docker compose, and deploy and run in a production-like environment. Copy the [docker-compose.yaml file from here](https://raw.githubusercontent.com/tensorlakeai/indexify/refs/heads/main/docker-compose.yaml).

```bash
Expand All @@ -119,7 +118,7 @@ This starts the server and two replicas of the exeuctor in separate containers.

This uses a default executor container based on Debian and a vanilla Python installation.

#### 5: Building Executor Images with Custom Dependencies
#### 6: Building Executor Images with Custom Dependencies

You can build custom images for functions that require additional Python or System dependencies.

Expand Down
50 changes: 21 additions & 29 deletions examples/readme/readme_example.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from pydantic import BaseModel
from indexify import indexify_function, Graph, indexify_router
from typing import List, Union
from indexify import indexify_function, indexify_router, Graph
from typing import List

class Total(BaseModel):
val: int = 0
Expand All @@ -9,38 +9,30 @@ class Total(BaseModel):
def generate_numbers(a: int) -> List[int]:
return [i for i in range(a)]

@indexify_function()
def square(x: int) -> int:
return x ** 2

@indexify_function(accumulate=Total)
def add(total: Total, new: int) -> Total:
total.val += new
return total

@indexify_function()
def square(total: Total) -> int:
return total.val ** 2

@indexify_function()
def cube(total: Total) -> int:
return total.val ** 3

@indexify_router()
def dynamic_router(val: Total) -> List[Union[square, cube]]:
if val.val % 2:
return [square]
return [cube]
g = Graph(name="sequence_summer", start_node=generate_numbers, description="Simple Sequence Summer")
g.add_edge(generate_numbers, square)
g.add_edge(square, add)

if __name__ == '__main__':
g = Graph(name="sequence_summer", start_node=generate_numbers, description="Simple Sequence Summer")
g.add_edge(generate_numbers, add)
g.add_edge(add, dynamic_router)
g.route(dynamic_router, [square, cube])

from indexify import create_client

client = create_client(in_process=True)
client.register_compute_graph(g)

invocation_id = client.invoke_graph_with_object("sequence_summer", block_until_done=True, a=4)
result = client.graph_outputs("sequence_summer", invocation_id, "squared")
if __name__ == "__main__":
invocation_id = g.run(a=10)
result = g.get_output(invocation_id, "add")
print(result)
result = client.graph_outputs("sequence_summer", invocation_id, "tripled")

from indexify import RemoteGraph
graph = RemoteGraph.deploy(g)
invocation_id = graph.run(block_until_done=True, a=10)
result = graph.get_output(invocation_id, "add")
print(result)

graph = RemoteGraph.by_name("sequence_summer")
invocation_id = graph.run(block_until_done=True, a=5)
print(graph.get_output(invocation_id, "add"))
2 changes: 1 addition & 1 deletion python-sdk/indexify/remote_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def foo(x: int) -> int:
)

@classmethod
def new(cls, g: Graph, server_url: Optional[str] = "http://localhost:8090"):
def deploy(cls, g: Graph, server_url: Optional[str] = "http://localhost:8090"):
"""
Create a new RemoteGraph from a local Graph object.
:param g: The local Graph object.
Expand Down
10 changes: 5 additions & 5 deletions python-sdk/tests/test_graph_behaviours.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,14 @@ def test_simple_function(self):
graph = Graph(
name="test_simple_function", description="test", start_node=simple_function
)
graph = RemoteGraph.new(graph)
graph = RemoteGraph.deploy(graph)
invocation_id = graph.run(block_until_done=True, x=MyObject(x="a"))
output = graph.get_output(invocation_id, "simple_function")
self.assertEqual(output, [MyObject(x="ab")])

def test_map_operation(self):
graph = create_pipeline_graph_with_map()
graph = RemoteGraph.new(graph)
graph = RemoteGraph.deploy(graph)
invocation_id = graph.run(block_until_done=True, x=3)
output_seq = graph.get_output(invocation_id, "generate_seq")
self.assertEqual(sorted(output_seq), [0, 1, 2])
Expand All @@ -117,7 +117,7 @@ def test_map_operation(self):

def test_map_reduce_operation(self):
graph = create_pipeline_graph_with_map_reduce()
graph = RemoteGraph.new(graph)
graph = RemoteGraph.deploy(graph)

invocation_id = graph.run(block_until_done=True, x=3)
output_sum_sq = graph.get_output(invocation_id, "sum_of_squares")
Expand All @@ -126,7 +126,7 @@ def test_map_reduce_operation(self):
self.assertEqual(output_str, ["5"])

def test_router_graph_behavior(self):
graph = RemoteGraph.new(create_router_graph())
graph = RemoteGraph.deploy(create_router_graph())
invocation_id = graph.run(block_until_done=True, x=3)

output_add_two = graph.get_output(invocation_id, "add_two")
Expand All @@ -145,7 +145,7 @@ def test_invoke_file(self):
graph = Graph(
name="test_handle_file", description="test", start_node=handle_file
)
graph = RemoteGraph.new(graph)
graph = RemoteGraph.deploy(graph)
import os

data = Path(os.path.dirname(__file__) + "/test_file").read_text()
Expand Down

0 comments on commit 9172ea8

Please sign in to comment.