langgraph-executor 0.0.1a1__py3-none-any.whl → 0.0.1a2__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.
@@ -45,6 +45,11 @@ class LangGraphExecutorStub(object):
45
45
  request_serializer=executor__pb2.GetGraphRequest.SerializeToString,
46
46
  response_deserializer=executor__pb2.GetGraphResponse.FromString,
47
47
  _registered_method=True)
48
+ self.GetAllGraphs = channel.unary_stream(
49
+ '/executor.LangGraphExecutor/GetAllGraphs',
50
+ request_serializer=executor__pb2.GetAllGraphsRequest.SerializeToString,
51
+ response_deserializer=executor__pb2.GetGraphResponse.FromString,
52
+ _registered_method=True)
48
53
  self.ChannelsFromCheckpoint = channel.unary_unary(
49
54
  '/executor.LangGraphExecutor/ChannelsFromCheckpoint',
50
55
  request_serializer=executor__pb2.ChannelsFromCheckpointRequest.SerializeToString,
@@ -85,6 +90,13 @@ class LangGraphExecutorServicer(object):
85
90
  context.set_details('Method not implemented!')
86
91
  raise NotImplementedError('Method not implemented!')
87
92
 
93
+ def GetAllGraphs(self, request, context):
94
+ """Get all supported graph definitions
95
+ """
96
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
97
+ context.set_details('Method not implemented!')
98
+ raise NotImplementedError('Method not implemented!')
99
+
88
100
  def ChannelsFromCheckpoint(self, request, context):
89
101
  """Get channels initialized from checkpoint
90
102
  """
@@ -126,6 +138,11 @@ def add_LangGraphExecutorServicer_to_server(servicer, server):
126
138
  request_deserializer=executor__pb2.GetGraphRequest.FromString,
127
139
  response_serializer=executor__pb2.GetGraphResponse.SerializeToString,
128
140
  ),
141
+ 'GetAllGraphs': grpc.unary_stream_rpc_method_handler(
142
+ servicer.GetAllGraphs,
143
+ request_deserializer=executor__pb2.GetAllGraphsRequest.FromString,
144
+ response_serializer=executor__pb2.GetGraphResponse.SerializeToString,
145
+ ),
129
146
  'ChannelsFromCheckpoint': grpc.unary_unary_rpc_method_handler(
130
147
  servicer.ChannelsFromCheckpoint,
131
148
  request_deserializer=executor__pb2.ChannelsFromCheckpointRequest.FromString,
@@ -212,6 +229,33 @@ class LangGraphExecutor(object):
212
229
  metadata,
213
230
  _registered_method=True)
214
231
 
232
+ @staticmethod
233
+ def GetAllGraphs(request,
234
+ target,
235
+ options=(),
236
+ channel_credentials=None,
237
+ call_credentials=None,
238
+ insecure=False,
239
+ compression=None,
240
+ wait_for_ready=None,
241
+ timeout=None,
242
+ metadata=None):
243
+ return grpc.experimental.unary_stream(
244
+ request,
245
+ target,
246
+ '/executor.LangGraphExecutor/GetAllGraphs',
247
+ executor__pb2.GetAllGraphsRequest.SerializeToString,
248
+ executor__pb2.GetGraphResponse.FromString,
249
+ options,
250
+ channel_credentials,
251
+ insecure,
252
+ call_credentials,
253
+ compression,
254
+ wait_for_ready,
255
+ timeout,
256
+ metadata,
257
+ _registered_method=True)
258
+
215
259
  @staticmethod
216
260
  def ChannelsFromCheckpoint(request,
217
261
  target,
@@ -33,6 +33,12 @@ class LangGraphExecutorStub:
33
33
  ]
34
34
  """Get graph definition"""
35
35
 
36
+ GetAllGraphs: grpc.UnaryStreamMultiCallable[
37
+ executor_pb2.GetAllGraphsRequest,
38
+ executor_pb2.GetGraphResponse,
39
+ ]
40
+ """Get all supported graph definitions"""
41
+
36
42
  ChannelsFromCheckpoint: grpc.UnaryUnaryMultiCallable[
37
43
  executor_pb2.ChannelsFromCheckpointRequest,
38
44
  executor_pb2.ChannelsFromCheckpointResponse,
@@ -72,6 +78,12 @@ class LangGraphExecutorAsyncStub:
72
78
  ]
73
79
  """Get graph definition"""
74
80
 
81
+ GetAllGraphs: grpc.aio.UnaryStreamMultiCallable[
82
+ executor_pb2.GetAllGraphsRequest,
83
+ executor_pb2.GetGraphResponse,
84
+ ]
85
+ """Get all supported graph definitions"""
86
+
75
87
  ChannelsFromCheckpoint: grpc.aio.UnaryUnaryMultiCallable[
76
88
  executor_pb2.ChannelsFromCheckpointRequest,
77
89
  executor_pb2.ChannelsFromCheckpointResponse,
@@ -115,6 +127,14 @@ class LangGraphExecutorServicer(metaclass=abc.ABCMeta):
115
127
  ) -> typing.Union[executor_pb2.GetGraphResponse, collections.abc.Awaitable[executor_pb2.GetGraphResponse]]:
116
128
  """Get graph definition"""
117
129
 
130
+ @abc.abstractmethod
131
+ def GetAllGraphs(
132
+ self,
133
+ request: executor_pb2.GetAllGraphsRequest,
134
+ context: _ServicerContext,
135
+ ) -> typing.Union[collections.abc.Iterator[executor_pb2.GetGraphResponse], collections.abc.AsyncIterator[executor_pb2.GetGraphResponse]]:
136
+ """Get all supported graph definitions"""
137
+
118
138
  @abc.abstractmethod
119
139
  def ChannelsFromCheckpoint(
120
140
  self,
@@ -1,4 +1,5 @@
1
1
  import argparse
2
+ import asyncio
2
3
  import logging
3
4
  import os
4
5
  import pathlib
@@ -6,18 +7,13 @@ import signal
6
7
  import sys
7
8
  import time
8
9
  import uuid
9
- from concurrent import futures
10
10
 
11
- import grpc
12
11
  from langgraph.pregel import Pregel
13
12
 
14
- from langgraph_executor.executor import LangGraphExecutorServicer
13
+ from langgraph_executor.executor import create_server
15
14
  from langgraph_executor.info_logger import ExecutorInfo, ExecutorInfoLogger
16
- from langgraph_executor.pb.executor_pb2_grpc import (
17
- add_LangGraphExecutorServicer_to_server,
18
- )
19
15
 
20
- EXECUTOR_DEFAULT_PORT = 50052
16
+ DEFAULT_EXECUTOR_ADDRESS = "127.0.0.1:50052"
21
17
 
22
18
  EXECUTOR_INFO_FILE_NAME = "info.json"
23
19
 
@@ -43,7 +39,6 @@ def setup_server_logging(component_id: str, debug=False, color=YELLOW):
43
39
  root_logger = logging.getLogger()
44
40
  for handler in root_logger.handlers[:]:
45
41
  root_logger.removeHandler(handler)
46
-
47
42
  # Configure logging
48
43
  logging.basicConfig(
49
44
  level=level,
@@ -63,11 +58,11 @@ def setup_server_logging(component_id: str, debug=False, color=YELLOW):
63
58
  )
64
59
 
65
60
 
66
- def create_executor_info(port: int, id: str):
61
+ def create_executor_info(address: str, id: str):
67
62
  return ExecutorInfo(
68
63
  id=id,
69
64
  pid=os.getpid(),
70
- port=port,
65
+ address=address,
71
66
  start_time=time.time(),
72
67
  status="starting",
73
68
  error_message=None,
@@ -82,10 +77,11 @@ def signum_to_name(signum):
82
77
  return f"UNKNOWN_SIGNAL_{signum}"
83
78
 
84
79
 
85
- def serve(
80
+ async def serve(
86
81
  graphs: dict[str, Pregel],
87
- port: int,
88
- debug: bool,
82
+ *,
83
+ address: str = DEFAULT_EXECUTOR_ADDRESS,
84
+ debug: bool = False,
89
85
  id: str | None = None,
90
86
  log_dir: pathlib.Path | None = None,
91
87
  ):
@@ -107,16 +103,17 @@ def serve(
107
103
  log_dir or pathlib.Path(__file__).resolve().parent.parent / "logs",
108
104
  )
109
105
 
110
- server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
111
- add_LangGraphExecutorServicer_to_server(LangGraphExecutorServicer(graphs), server)
112
- port = server.add_insecure_port(f"[::]:{port}")
106
+ server = create_server(graphs, address)
113
107
 
114
- server.start()
108
+ await server.start()
109
+ loop = asyncio.get_event_loop()
115
110
 
116
111
  # Signal handler for graceful shutdown
117
112
  def signal_handler(signum, frame):
118
113
  logger.info(f"Received signal {signum_to_name(signum)}. Shutting down...")
119
- server.stop(5) # Give 5 seconds for graceful shutdown
114
+ asyncio.run_coroutine_threadsafe(
115
+ server.stop(5), loop
116
+ ) # Give 5 seconds for graceful shutdown
120
117
  info_logger.update_executor_info(
121
118
  executor_info.id,
122
119
  status="stopped",
@@ -130,16 +127,16 @@ def serve(
130
127
  signal.signal(signal.SIGINT, signal_handler)
131
128
  signal.signal(signal.SIGTERM, signal_handler)
132
129
 
133
- executor_info = create_executor_info(port, id_)
130
+ executor_info = create_executor_info(address, id_)
134
131
  info_logger.write_executor_info(executor_info)
135
132
 
136
133
  try:
137
134
  info_logger.update_executor_info(executor_info.id, status="running")
138
- logger.info("Listening...")
139
- server.wait_for_termination()
135
+ logger.info(f"Listening at address {address}...")
136
+ await server.wait_for_termination()
140
137
  except Exception as e:
141
138
  logger.exception("Unexpected error in executor")
142
- server.stop(0)
139
+ await server.stop(0)
143
140
  info_logger.update_executor_info(
144
141
  executor_info.id,
145
142
  status="error",
@@ -152,8 +149,8 @@ def serve(
152
149
  def main():
153
150
  """Start a LangGraph executor server."""
154
151
  parser = argparse.ArgumentParser()
155
- parser.add_argument("--port", type=int, default=EXECUTOR_DEFAULT_PORT)
156
- parser.add_argument("--debug", action="store_true")
152
+ parser.add_argument("--address", type=int, default=DEFAULT_EXECUTOR_ADDRESS)
153
+ parser.add_argument("--debug", action="store_false")
157
154
  parser.add_argument(
158
155
  "--log-dir",
159
156
  type=pathlib.Path,
@@ -179,7 +176,7 @@ def main():
179
176
  graphs = GRAPHS
180
177
 
181
178
  # serve
182
- serve(graphs, args.port, args.debug, log_dir=args.log_dir)
179
+ serve(graphs, address=args.address, debug=args.debug, log_dir=args.log_dir)
183
180
 
184
181
 
185
182
  if __name__ == "__main__":
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langgraph-executor
3
- Version: 0.0.1a1
3
+ Version: 0.0.1a2
4
4
  Summary: LangGraph python RPC server executable by the langgraph-go orchestrator.
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: grpcio>=1.73.1
@@ -1,19 +1,20 @@
1
- langgraph_executor/__init__.py,sha256=qEdg2MhZc4iFQOS_8-O-er6N8n5kRoiTg9Mrx_ssBJ8,24
1
+ langgraph_executor/__init__.py,sha256=3EXaFnXv1z-8AVCGrDM9MpCrpg8I15YhcHCsHzX3iGI,24
2
2
  langgraph_executor/common.py,sha256=w75Bqbrj5LOtiWoOOdIi45yVB05xYXDAnokwg7MgDQE,13688
3
3
  langgraph_executor/example.py,sha256=TcfxgC9VfpZFliWnuVdJMllCDa8ji7vrSCRWnmdsUA8,900
4
- langgraph_executor/execute_task.py,sha256=-QwlbWlE8uUNFkIVtvcaWUeu4HszDF5fxTixHnE7JZk,7459
5
- langgraph_executor/executor.py,sha256=vCvEpL1QhPXgz5J2fbyeJ39_98x78cnTp-DU_Js0AAQ,14688
4
+ langgraph_executor/execute_task.py,sha256=_m-WyVODhShI29qzkK0DXSPoTY4E_izbuaT7F_fVZVw,7262
5
+ langgraph_executor/executor.py,sha256=oUg6q8WWjAIwuh2ik76IbCPMKfmegT5ePZsWFnvR4WE,5296
6
+ langgraph_executor/executor_base.py,sha256=OpFhZNd-FehaTkSlnmD4bw9cAQ3FF8nWO9mim5YL0Cg,18509
6
7
  langgraph_executor/extract_graph.py,sha256=f7NNeZigRQlTAYg_-mV8eBgQ9q8kuThCDwLjRO6wReQ,6365
7
- langgraph_executor/info_logger.py,sha256=BUcrg_nui_dN4JBUVyO7jurmCnt8gQ0TOubUNbyvYBk,3095
8
+ langgraph_executor/info_logger.py,sha256=kgoVnMxm_aloHal89NHfH_Qb9eixrqD0dHmgnrm_vL4,3110
8
9
  langgraph_executor/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- langgraph_executor/server.py,sha256=avtZzStLiIDvNCKyytFU3E2Li1_TBgz5oyWUBRbPzFk,5200
10
+ langgraph_executor/server.py,sha256=EVwZjsO2S0qhhU9C_4e85gfrxyOCo3H72bBi28vSFIw,5134
10
11
  langgraph_executor/setup.sh,sha256=QI505EIya8sjEIohom6GDfFckFqOMF8bIEX-hSWcLUI,627
11
12
  langgraph_executor/stream_utils.py,sha256=snxlEoZe0d4ae3h_6Ct3zNzLV_ugvPANcr4VECYofwk,2974
12
13
  langgraph_executor/pb/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- langgraph_executor/pb/executor_pb2.py,sha256=cFwtWNUw8jxoKpA8EE2XGHg2uBgZYRInM9VLTD9keuY,8196
14
- langgraph_executor/pb/executor_pb2.pyi,sha256=CjyrE4iJSReAWokBgD8L4TMj1dZv0PvW8jYMtIFVHWA,17535
15
- langgraph_executor/pb/executor_pb2_grpc.py,sha256=IvKDVBWxrWU7Rcntall4KAvpQ8CdLkbljKaCEloimQE,12224
16
- langgraph_executor/pb/executor_pb2_grpc.pyi,sha256=iGHLqEpl7FFrBvBmBfbacvl0YgtZf8dH5pBkAaB0d64,5270
14
+ langgraph_executor/pb/executor_pb2.py,sha256=ny5SLOq4VqbZ-1XxPdytfi3Y-H5FuQwL4CK3fgMh_EI,8617
15
+ langgraph_executor/pb/executor_pb2.pyi,sha256=iVySzUzD9REkvJzet00YOL9Be3YCRizCqnsvGU_oYD4,18612
16
+ langgraph_executor/pb/executor_pb2_grpc.py,sha256=tsYWd0X0hmGPOO_Vf-4Pv0-vgMutzaTOTM_UnDjUeIc,13938
17
+ langgraph_executor/pb/executor_pb2_grpc.pyi,sha256=5ipWaunudj0rGP1yoRRf3V-2kjKiMkr4HHIuGqUa24s,5979
17
18
  langgraph_executor/pb/graph_pb2.py,sha256=V4by2e0nEN-oF6AeX-SSzgN96d8BbE923p91Cp91UFQ,4021
18
19
  langgraph_executor/pb/graph_pb2.pyi,sha256=xmhlJdwZ6g-ckwxjLKEIs7pJPiGIbin9m2rqdKMOWyI,9470
19
20
  langgraph_executor/pb/graph_pb2_grpc.py,sha256=8j8j0GTUo21GL7RO-_UgVPN27DRnAfus0lhTWKI49no,886
@@ -26,6 +27,6 @@ langgraph_executor/pb/types_pb2.py,sha256=rUboWBthlLM-iJOmZZta-HSekwTNFuXfWLaYHe
26
27
  langgraph_executor/pb/types_pb2.pyi,sha256=tBX4LzmfWZ-IYscIeAEBTDC02GWWKEAQVB2JPNHChDc,40957
27
28
  langgraph_executor/pb/types_pb2_grpc.py,sha256=EPv87wCc-6BNJ2xTNcb9d3ictDerK5cBt7qhd7EmJiQ,886
28
29
  langgraph_executor/pb/types_pb2_grpc.pyi,sha256=Dl8kkjhqb6F1Kt24mcFg7ppish4iKVfjRiiBxEjsMMA,413
29
- langgraph_executor-0.0.1a1.dist-info/METADATA,sha256=pZesnbhRr1FPbzudYlalRzmxb5sj9ytDzuc5k9PKjrU,433
30
- langgraph_executor-0.0.1a1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
31
- langgraph_executor-0.0.1a1.dist-info/RECORD,,
30
+ langgraph_executor-0.0.1a2.dist-info/METADATA,sha256=-xr_G-Z1Huy6YMjYSJHYZZkPD_tu7Q-ZwDgLluOmkTo,433
31
+ langgraph_executor-0.0.1a2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
32
+ langgraph_executor-0.0.1a2.dist-info/RECORD,,