From 038ee7a2238fe279a536a40509a3a24375f2b5a5 Mon Sep 17 00:00:00 2001 From: Vaibhav Tiwari Date: Thu, 26 Mar 2026 19:25:07 -0400 Subject: [PATCH 01/14] feat: Sourcer changes: * deprecate partitions_handler, * Add support for active_partitions_handler and total_partitions, * Maintain backward compatibility Signed-off-by: Vaibhav Tiwari --- .../proto/accumulator/accumulator_pb2_grpc.py | 4 +- .../proto/common/metadata_pb2_grpc.py | 4 +- .../pynumaflow/proto/mapper/map_pb2_grpc.py | 4 +- .../proto/reducer/reduce_pb2_grpc.py | 4 +- .../proto/sideinput/sideinput_pb2_grpc.py | 4 +- .../pynumaflow/proto/sinker/sink_pb2_grpc.py | 4 +- .../pynumaflow/proto/sourcer/source.proto | 4 +- .../pynumaflow/proto/sourcer/source_pb2.py | 18 +++--- .../pynumaflow/proto/sourcer/source_pb2.pyi | 6 +- .../proto/sourcer/source_pb2_grpc.py | 4 +- .../sourcetransformer/transform_pb2_grpc.py | 4 +- .../pynumaflow/pynumaflow/sourcer/_dtypes.py | 48 +++++++++++++--- .../sourcer/servicer/async_servicer.py | 14 +++-- .../tests/source/test_async_source.py | 56 +++++++++++++++++++ packages/pynumaflow/tests/source/utils.py | 34 +++++++++++ 15 files changed, 171 insertions(+), 41 deletions(-) diff --git a/packages/pynumaflow/pynumaflow/proto/accumulator/accumulator_pb2_grpc.py b/packages/pynumaflow/pynumaflow/proto/accumulator/accumulator_pb2_grpc.py index e8a6e86d..a7ad3972 100644 --- a/packages/pynumaflow/pynumaflow/proto/accumulator/accumulator_pb2_grpc.py +++ b/packages/pynumaflow/pynumaflow/proto/accumulator/accumulator_pb2_grpc.py @@ -6,7 +6,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from pynumaflow.proto.accumulator import accumulator_pb2 as pynumaflow_dot_proto_dot_accumulator_dot_accumulator__pb2 -GRPC_GENERATED_VERSION = '1.75.0' +GRPC_GENERATED_VERSION = '1.78.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -19,7 +19,7 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + f' but the generated code in pynumaflow/proto/accumulator/accumulator_pb2_grpc.py depends on' + + ' but the generated code in pynumaflow/proto/accumulator/accumulator_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' diff --git a/packages/pynumaflow/pynumaflow/proto/common/metadata_pb2_grpc.py b/packages/pynumaflow/pynumaflow/proto/common/metadata_pb2_grpc.py index 2e60d47a..9691c0c4 100644 --- a/packages/pynumaflow/pynumaflow/proto/common/metadata_pb2_grpc.py +++ b/packages/pynumaflow/pynumaflow/proto/common/metadata_pb2_grpc.py @@ -4,7 +4,7 @@ import warnings -GRPC_GENERATED_VERSION = '1.75.0' +GRPC_GENERATED_VERSION = '1.78.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -17,7 +17,7 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + f' but the generated code in pynumaflow/proto/common/metadata_pb2_grpc.py depends on' + + ' but the generated code in pynumaflow/proto/common/metadata_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' diff --git a/packages/pynumaflow/pynumaflow/proto/mapper/map_pb2_grpc.py b/packages/pynumaflow/pynumaflow/proto/mapper/map_pb2_grpc.py index 7325b904..cf4a2d11 100644 --- a/packages/pynumaflow/pynumaflow/proto/mapper/map_pb2_grpc.py +++ b/packages/pynumaflow/pynumaflow/proto/mapper/map_pb2_grpc.py @@ -6,7 +6,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from pynumaflow.proto.mapper import map_pb2 as pynumaflow_dot_proto_dot_mapper_dot_map__pb2 -GRPC_GENERATED_VERSION = '1.75.0' +GRPC_GENERATED_VERSION = '1.78.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -19,7 +19,7 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + f' but the generated code in pynumaflow/proto/mapper/map_pb2_grpc.py depends on' + + ' but the generated code in pynumaflow/proto/mapper/map_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' diff --git a/packages/pynumaflow/pynumaflow/proto/reducer/reduce_pb2_grpc.py b/packages/pynumaflow/pynumaflow/proto/reducer/reduce_pb2_grpc.py index 4a8dd390..88a589dc 100644 --- a/packages/pynumaflow/pynumaflow/proto/reducer/reduce_pb2_grpc.py +++ b/packages/pynumaflow/pynumaflow/proto/reducer/reduce_pb2_grpc.py @@ -6,7 +6,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from pynumaflow.proto.reducer import reduce_pb2 as pynumaflow_dot_proto_dot_reducer_dot_reduce__pb2 -GRPC_GENERATED_VERSION = '1.75.0' +GRPC_GENERATED_VERSION = '1.78.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -19,7 +19,7 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + f' but the generated code in pynumaflow/proto/reducer/reduce_pb2_grpc.py depends on' + + ' but the generated code in pynumaflow/proto/reducer/reduce_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' diff --git a/packages/pynumaflow/pynumaflow/proto/sideinput/sideinput_pb2_grpc.py b/packages/pynumaflow/pynumaflow/proto/sideinput/sideinput_pb2_grpc.py index 2f1c8203..a34c0e47 100644 --- a/packages/pynumaflow/pynumaflow/proto/sideinput/sideinput_pb2_grpc.py +++ b/packages/pynumaflow/pynumaflow/proto/sideinput/sideinput_pb2_grpc.py @@ -6,7 +6,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from pynumaflow.proto.sideinput import sideinput_pb2 as pynumaflow_dot_proto_dot_sideinput_dot_sideinput__pb2 -GRPC_GENERATED_VERSION = '1.75.0' +GRPC_GENERATED_VERSION = '1.78.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -19,7 +19,7 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + f' but the generated code in pynumaflow/proto/sideinput/sideinput_pb2_grpc.py depends on' + + ' but the generated code in pynumaflow/proto/sideinput/sideinput_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' diff --git a/packages/pynumaflow/pynumaflow/proto/sinker/sink_pb2_grpc.py b/packages/pynumaflow/pynumaflow/proto/sinker/sink_pb2_grpc.py index cecd2790..010b5352 100644 --- a/packages/pynumaflow/pynumaflow/proto/sinker/sink_pb2_grpc.py +++ b/packages/pynumaflow/pynumaflow/proto/sinker/sink_pb2_grpc.py @@ -6,7 +6,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from pynumaflow.proto.sinker import sink_pb2 as pynumaflow_dot_proto_dot_sinker_dot_sink__pb2 -GRPC_GENERATED_VERSION = '1.75.0' +GRPC_GENERATED_VERSION = '1.78.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -19,7 +19,7 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + f' but the generated code in pynumaflow/proto/sinker/sink_pb2_grpc.py depends on' + + ' but the generated code in pynumaflow/proto/sinker/sink_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' diff --git a/packages/pynumaflow/pynumaflow/proto/sourcer/source.proto b/packages/pynumaflow/pynumaflow/proto/sourcer/source.proto index c3551203..9bcd4aff 100644 --- a/packages/pynumaflow/pynumaflow/proto/sourcer/source.proto +++ b/packages/pynumaflow/pynumaflow/proto/sourcer/source.proto @@ -190,8 +190,10 @@ message PendingResponse { */ message PartitionsResponse { message Result { - // Required field holding the list of partitions. + // Required field holding the list of active partitions. repeated int32 partitions = 1; + // Total number of partitions in the source. + optional int32 total_partitions = 2; } // Required field holding the result. Result result = 1; diff --git a/packages/pynumaflow/pynumaflow/proto/sourcer/source_pb2.py b/packages/pynumaflow/pynumaflow/proto/sourcer/source_pb2.py index b6ac0107..041838f8 100644 --- a/packages/pynumaflow/pynumaflow/proto/sourcer/source_pb2.py +++ b/packages/pynumaflow/pynumaflow/proto/sourcer/source_pb2.py @@ -27,7 +27,7 @@ from pynumaflow.proto.common import metadata_pb2 as pynumaflow_dot_proto_dot_common_dot_metadata__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%pynumaflow/proto/sourcer/source.proto\x12\tsource.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a&pynumaflow/proto/common/metadata.proto\"\x18\n\tHandshake\x12\x0b\n\x03sot\x18\x01 \x01(\x08\"\xb1\x01\n\x0bReadRequest\x12/\n\x07request\x18\x01 \x01(\x0b\x32\x1e.source.v1.ReadRequest.Request\x12,\n\thandshake\x18\x02 \x01(\x0b\x32\x14.source.v1.HandshakeH\x00\x88\x01\x01\x1a\x35\n\x07Request\x12\x13\n\x0bnum_records\x18\x01 \x01(\x04\x12\x15\n\rtimeout_in_ms\x18\x02 \x01(\rB\x0c\n\n_handshake\"\xa5\x05\n\x0cReadResponse\x12.\n\x06result\x18\x01 \x01(\x0b\x32\x1e.source.v1.ReadResponse.Result\x12.\n\x06status\x18\x02 \x01(\x0b\x32\x1e.source.v1.ReadResponse.Status\x12,\n\thandshake\x18\x03 \x01(\x0b\x32\x14.source.v1.HandshakeH\x00\x88\x01\x01\x1a\x8c\x02\n\x06Result\x12\x0f\n\x07payload\x18\x01 \x01(\x0c\x12!\n\x06offset\x18\x02 \x01(\x0b\x32\x11.source.v1.Offset\x12.\n\nevent_time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0c\n\x04keys\x18\x04 \x03(\t\x12<\n\x07headers\x18\x05 \x03(\x0b\x32+.source.v1.ReadResponse.Result.HeadersEntry\x12\"\n\x08metadata\x18\x06 \x01(\x0b\x32\x10.common.Metadata\x1a.\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\xe9\x01\n\x06Status\x12\x0b\n\x03\x65ot\x18\x01 \x01(\x08\x12\x31\n\x04\x63ode\x18\x02 \x01(\x0e\x32#.source.v1.ReadResponse.Status.Code\x12\x38\n\x05\x65rror\x18\x03 \x01(\x0e\x32$.source.v1.ReadResponse.Status.ErrorH\x00\x88\x01\x01\x12\x10\n\x03msg\x18\x04 \x01(\tH\x01\x88\x01\x01\" \n\x04\x43ode\x12\x0b\n\x07SUCCESS\x10\x00\x12\x0b\n\x07\x46\x41ILURE\x10\x01\"\x1f\n\x05\x45rror\x12\x0b\n\x07UNACKED\x10\x00\x12\t\n\x05OTHER\x10\x01\x42\x08\n\x06_errorB\x06\n\x04_msgB\x0c\n\n_handshake\"\xa7\x01\n\nAckRequest\x12.\n\x07request\x18\x01 \x01(\x0b\x32\x1d.source.v1.AckRequest.Request\x12,\n\thandshake\x18\x02 \x01(\x0b\x32\x14.source.v1.HandshakeH\x00\x88\x01\x01\x1a-\n\x07Request\x12\"\n\x07offsets\x18\x01 \x03(\x0b\x32\x11.source.v1.OffsetB\x0c\n\n_handshake\"\xab\x01\n\x0b\x41\x63kResponse\x12-\n\x06result\x18\x01 \x01(\x0b\x32\x1d.source.v1.AckResponse.Result\x12,\n\thandshake\x18\x02 \x01(\x0b\x32\x14.source.v1.HandshakeH\x00\x88\x01\x01\x1a\x31\n\x06Result\x12\'\n\x07success\x18\x01 \x01(\x0b\x32\x16.google.protobuf.EmptyB\x0c\n\n_handshake\"m\n\x0bNackRequest\x12/\n\x07request\x18\x01 \x01(\x0b\x32\x1e.source.v1.NackRequest.Request\x1a-\n\x07Request\x12\"\n\x07offsets\x18\x01 \x03(\x0b\x32\x11.source.v1.Offset\"q\n\x0cNackResponse\x12.\n\x06result\x18\x01 \x01(\x0b\x32\x1e.source.v1.NackResponse.Result\x1a\x31\n\x06Result\x12\'\n\x07success\x18\x01 \x01(\x0b\x32\x16.google.protobuf.Empty\"\x1e\n\rReadyResponse\x12\r\n\x05ready\x18\x01 \x01(\x08\"]\n\x0fPendingResponse\x12\x31\n\x06result\x18\x01 \x01(\x0b\x32!.source.v1.PendingResponse.Result\x1a\x17\n\x06Result\x12\r\n\x05\x63ount\x18\x01 \x01(\x03\"h\n\x12PartitionsResponse\x12\x34\n\x06result\x18\x01 \x01(\x0b\x32$.source.v1.PartitionsResponse.Result\x1a\x1c\n\x06Result\x12\x12\n\npartitions\x18\x01 \x03(\x05\".\n\x06Offset\x12\x0e\n\x06offset\x18\x01 \x01(\x0c\x12\x14\n\x0cpartition_id\x18\x02 \x01(\x05\x32\x83\x03\n\x06Source\x12=\n\x06ReadFn\x12\x16.source.v1.ReadRequest\x1a\x17.source.v1.ReadResponse(\x01\x30\x01\x12:\n\x05\x41\x63kFn\x12\x15.source.v1.AckRequest\x1a\x16.source.v1.AckResponse(\x01\x30\x01\x12\x39\n\x06NackFn\x12\x16.source.v1.NackRequest\x1a\x17.source.v1.NackResponse\x12?\n\tPendingFn\x12\x16.google.protobuf.Empty\x1a\x1a.source.v1.PendingResponse\x12\x45\n\x0cPartitionsFn\x12\x16.google.protobuf.Empty\x1a\x1d.source.v1.PartitionsResponse\x12;\n\x07IsReady\x12\x16.google.protobuf.Empty\x1a\x18.source.v1.ReadyResponseb\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%pynumaflow/proto/sourcer/source.proto\x12\tsource.v1\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a&pynumaflow/proto/common/metadata.proto\"\x18\n\tHandshake\x12\x0b\n\x03sot\x18\x01 \x01(\x08\"\xb1\x01\n\x0bReadRequest\x12/\n\x07request\x18\x01 \x01(\x0b\x32\x1e.source.v1.ReadRequest.Request\x12,\n\thandshake\x18\x02 \x01(\x0b\x32\x14.source.v1.HandshakeH\x00\x88\x01\x01\x1a\x35\n\x07Request\x12\x13\n\x0bnum_records\x18\x01 \x01(\x04\x12\x15\n\rtimeout_in_ms\x18\x02 \x01(\rB\x0c\n\n_handshake\"\xa5\x05\n\x0cReadResponse\x12.\n\x06result\x18\x01 \x01(\x0b\x32\x1e.source.v1.ReadResponse.Result\x12.\n\x06status\x18\x02 \x01(\x0b\x32\x1e.source.v1.ReadResponse.Status\x12,\n\thandshake\x18\x03 \x01(\x0b\x32\x14.source.v1.HandshakeH\x00\x88\x01\x01\x1a\x8c\x02\n\x06Result\x12\x0f\n\x07payload\x18\x01 \x01(\x0c\x12!\n\x06offset\x18\x02 \x01(\x0b\x32\x11.source.v1.Offset\x12.\n\nevent_time\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0c\n\x04keys\x18\x04 \x03(\t\x12<\n\x07headers\x18\x05 \x03(\x0b\x32+.source.v1.ReadResponse.Result.HeadersEntry\x12\"\n\x08metadata\x18\x06 \x01(\x0b\x32\x10.common.Metadata\x1a.\n\x0cHeadersEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\xe9\x01\n\x06Status\x12\x0b\n\x03\x65ot\x18\x01 \x01(\x08\x12\x31\n\x04\x63ode\x18\x02 \x01(\x0e\x32#.source.v1.ReadResponse.Status.Code\x12\x38\n\x05\x65rror\x18\x03 \x01(\x0e\x32$.source.v1.ReadResponse.Status.ErrorH\x00\x88\x01\x01\x12\x10\n\x03msg\x18\x04 \x01(\tH\x01\x88\x01\x01\" \n\x04\x43ode\x12\x0b\n\x07SUCCESS\x10\x00\x12\x0b\n\x07\x46\x41ILURE\x10\x01\"\x1f\n\x05\x45rror\x12\x0b\n\x07UNACKED\x10\x00\x12\t\n\x05OTHER\x10\x01\x42\x08\n\x06_errorB\x06\n\x04_msgB\x0c\n\n_handshake\"\xa7\x01\n\nAckRequest\x12.\n\x07request\x18\x01 \x01(\x0b\x32\x1d.source.v1.AckRequest.Request\x12,\n\thandshake\x18\x02 \x01(\x0b\x32\x14.source.v1.HandshakeH\x00\x88\x01\x01\x1a-\n\x07Request\x12\"\n\x07offsets\x18\x01 \x03(\x0b\x32\x11.source.v1.OffsetB\x0c\n\n_handshake\"\xab\x01\n\x0b\x41\x63kResponse\x12-\n\x06result\x18\x01 \x01(\x0b\x32\x1d.source.v1.AckResponse.Result\x12,\n\thandshake\x18\x02 \x01(\x0b\x32\x14.source.v1.HandshakeH\x00\x88\x01\x01\x1a\x31\n\x06Result\x12\'\n\x07success\x18\x01 \x01(\x0b\x32\x16.google.protobuf.EmptyB\x0c\n\n_handshake\"m\n\x0bNackRequest\x12/\n\x07request\x18\x01 \x01(\x0b\x32\x1e.source.v1.NackRequest.Request\x1a-\n\x07Request\x12\"\n\x07offsets\x18\x01 \x03(\x0b\x32\x11.source.v1.Offset\"q\n\x0cNackResponse\x12.\n\x06result\x18\x01 \x01(\x0b\x32\x1e.source.v1.NackResponse.Result\x1a\x31\n\x06Result\x12\'\n\x07success\x18\x01 \x01(\x0b\x32\x16.google.protobuf.Empty\"\x1e\n\rReadyResponse\x12\r\n\x05ready\x18\x01 \x01(\x08\"]\n\x0fPendingResponse\x12\x31\n\x06result\x18\x01 \x01(\x0b\x32!.source.v1.PendingResponse.Result\x1a\x17\n\x06Result\x12\r\n\x05\x63ount\x18\x01 \x01(\x03\"\x9c\x01\n\x12PartitionsResponse\x12\x34\n\x06result\x18\x01 \x01(\x0b\x32$.source.v1.PartitionsResponse.Result\x1aP\n\x06Result\x12\x12\n\npartitions\x18\x01 \x03(\x05\x12\x1d\n\x10total_partitions\x18\x02 \x01(\x05H\x00\x88\x01\x01\x42\x13\n\x11_total_partitions\".\n\x06Offset\x12\x0e\n\x06offset\x18\x01 \x01(\x0c\x12\x14\n\x0cpartition_id\x18\x02 \x01(\x05\x32\x83\x03\n\x06Source\x12=\n\x06ReadFn\x12\x16.source.v1.ReadRequest\x1a\x17.source.v1.ReadResponse(\x01\x30\x01\x12:\n\x05\x41\x63kFn\x12\x15.source.v1.AckRequest\x1a\x16.source.v1.AckResponse(\x01\x30\x01\x12\x39\n\x06NackFn\x12\x16.source.v1.NackRequest\x1a\x17.source.v1.NackResponse\x12?\n\tPendingFn\x12\x16.google.protobuf.Empty\x1a\x1a.source.v1.PendingResponse\x12\x45\n\x0cPartitionsFn\x12\x16.google.protobuf.Empty\x1a\x1d.source.v1.PartitionsResponse\x12;\n\x07IsReady\x12\x16.google.protobuf.Empty\x1a\x18.source.v1.ReadyResponseb\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -76,12 +76,12 @@ _globals['_PENDINGRESPONSE']._serialized_end=1735 _globals['_PENDINGRESPONSE_RESULT']._serialized_start=1712 _globals['_PENDINGRESPONSE_RESULT']._serialized_end=1735 - _globals['_PARTITIONSRESPONSE']._serialized_start=1737 - _globals['_PARTITIONSRESPONSE']._serialized_end=1841 - _globals['_PARTITIONSRESPONSE_RESULT']._serialized_start=1813 - _globals['_PARTITIONSRESPONSE_RESULT']._serialized_end=1841 - _globals['_OFFSET']._serialized_start=1843 - _globals['_OFFSET']._serialized_end=1889 - _globals['_SOURCE']._serialized_start=1892 - _globals['_SOURCE']._serialized_end=2279 + _globals['_PARTITIONSRESPONSE']._serialized_start=1738 + _globals['_PARTITIONSRESPONSE']._serialized_end=1894 + _globals['_PARTITIONSRESPONSE_RESULT']._serialized_start=1814 + _globals['_PARTITIONSRESPONSE_RESULT']._serialized_end=1894 + _globals['_OFFSET']._serialized_start=1896 + _globals['_OFFSET']._serialized_end=1942 + _globals['_SOURCE']._serialized_start=1945 + _globals['_SOURCE']._serialized_end=2332 # @@protoc_insertion_point(module_scope) diff --git a/packages/pynumaflow/pynumaflow/proto/sourcer/source_pb2.pyi b/packages/pynumaflow/pynumaflow/proto/sourcer/source_pb2.pyi index 16925099..c347cfc5 100644 --- a/packages/pynumaflow/pynumaflow/proto/sourcer/source_pb2.pyi +++ b/packages/pynumaflow/pynumaflow/proto/sourcer/source_pb2.pyi @@ -156,10 +156,12 @@ class PendingResponse(_message.Message): class PartitionsResponse(_message.Message): __slots__ = ("result",) class Result(_message.Message): - __slots__ = ("partitions",) + __slots__ = ("partitions", "total_partitions") PARTITIONS_FIELD_NUMBER: _ClassVar[int] + TOTAL_PARTITIONS_FIELD_NUMBER: _ClassVar[int] partitions: _containers.RepeatedScalarFieldContainer[int] - def __init__(self, partitions: _Optional[_Iterable[int]] = ...) -> None: ... + total_partitions: int + def __init__(self, partitions: _Optional[_Iterable[int]] = ..., total_partitions: _Optional[int] = ...) -> None: ... RESULT_FIELD_NUMBER: _ClassVar[int] result: PartitionsResponse.Result def __init__(self, result: _Optional[_Union[PartitionsResponse.Result, _Mapping]] = ...) -> None: ... diff --git a/packages/pynumaflow/pynumaflow/proto/sourcer/source_pb2_grpc.py b/packages/pynumaflow/pynumaflow/proto/sourcer/source_pb2_grpc.py index 6dd4103d..0fd4fb05 100644 --- a/packages/pynumaflow/pynumaflow/proto/sourcer/source_pb2_grpc.py +++ b/packages/pynumaflow/pynumaflow/proto/sourcer/source_pb2_grpc.py @@ -6,7 +6,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from pynumaflow.proto.sourcer import source_pb2 as pynumaflow_dot_proto_dot_sourcer_dot_source__pb2 -GRPC_GENERATED_VERSION = '1.75.0' +GRPC_GENERATED_VERSION = '1.78.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -19,7 +19,7 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + f' but the generated code in pynumaflow/proto/sourcer/source_pb2_grpc.py depends on' + + ' but the generated code in pynumaflow/proto/sourcer/source_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' diff --git a/packages/pynumaflow/pynumaflow/proto/sourcetransformer/transform_pb2_grpc.py b/packages/pynumaflow/pynumaflow/proto/sourcetransformer/transform_pb2_grpc.py index 942c4450..9ad98b7d 100644 --- a/packages/pynumaflow/pynumaflow/proto/sourcetransformer/transform_pb2_grpc.py +++ b/packages/pynumaflow/pynumaflow/proto/sourcetransformer/transform_pb2_grpc.py @@ -6,7 +6,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from pynumaflow.proto.sourcetransformer import transform_pb2 as pynumaflow_dot_proto_dot_sourcetransformer_dot_transform__pb2 -GRPC_GENERATED_VERSION = '1.75.0' +GRPC_GENERATED_VERSION = '1.78.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -19,7 +19,7 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + f' but the generated code in pynumaflow/proto/sourcetransformer/transform_pb2_grpc.py depends on' + + ' but the generated code in pynumaflow/proto/sourcetransformer/transform_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' diff --git a/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py b/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py index 4f407483..65c0843a 100644 --- a/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py +++ b/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py @@ -1,4 +1,5 @@ import os +import warnings from abc import ABCMeta, abstractmethod from collections.abc import AsyncIterator, Callable, Iterator from dataclasses import dataclass @@ -240,25 +241,32 @@ def count(self) -> int: class PartitionsResponse: """ PartitionsResponse is the response for the partition request. - It indicates the number of partitions at the user defined source. - A negative count indicates that the partition information is not available. + It indicates the active partitions at the user defined source. Args: - count: the number of partitions. + partitions: the list of active partitions. + total_partitions: the total number of partitions in the source (optional). """ _partitions: list[int] + _total_partitions: int | None - def __init__(self, partitions: list[int]): + def __init__(self, partitions: list[int], total_partitions: int | None = None): if not isinstance(partitions, list): raise TypeError(f"Wrong data type: {type(partitions)} for Partition.partitions") self._partitions = partitions + self._total_partitions = total_partitions @property def partitions(self) -> list[int]: - """Returns the list of partitions""" + """Returns the list of active partitions""" return self._partitions + @property + def total_partitions(self) -> int | None: + """Returns the total number of partitions, or None if not available""" + return self._total_partitions + class Sourcer(metaclass=ABCMeta): """ @@ -297,12 +305,36 @@ async def pending_handler(self) -> PendingResponse: """ pass - @abstractmethod async def partitions_handler(self) -> PartitionsResponse: """ - The simple source always returns zero to indicate there is no pending record. + .. deprecated:: + Use :meth:`active_partitions_handler` instead. + + Returns the active partitions associated with the source. """ - pass + warnings.warn( + "partitions_handler is deprecated, use active_partitions_handler instead.", + DeprecationWarning, + stacklevel=2, + ) + return PartitionsResponse(partitions=get_default_partitions()) + + async def active_partitions_handler(self) -> PartitionsResponse: + """ + Returns the active partitions associated with the source, used by the platform + to determine the partitions to which the watermark should be published. + Falls back to partitions_handler() if not overridden. + """ + return await self.partitions_handler() + + async def total_partitions_handler(self) -> int | None: + """ + Returns the total number of partitions in the source. + Used by the platform for watermark progression to know when all + processors have reported in. + Returns None by default, indicating the source does not report total partitions. + """ + return None # Create default partition id from the environment variable "NUMAFLOW_REPLICA" diff --git a/packages/pynumaflow/pynumaflow/sourcer/servicer/async_servicer.py b/packages/pynumaflow/pynumaflow/sourcer/servicer/async_servicer.py index 51cd74c2..d68a62cf 100644 --- a/packages/pynumaflow/pynumaflow/sourcer/servicer/async_servicer.py +++ b/packages/pynumaflow/pynumaflow/sourcer/servicer/async_servicer.py @@ -84,7 +84,8 @@ def __initialize_handlers(self): self.__source_ack_handler = self.source_handler.ack_handler self.__source_nack_handler = self.source_handler.nack_handler self.__source_pending_handler = self.source_handler.pending_handler - self.__source_partitions_handler = self.source_handler.partitions_handler + self.__source_active_partitions_handler = self.source_handler.active_partitions_handler + self.__source_total_partitions_handler = self.source_handler.total_partitions_handler async def ReadFn( self, @@ -278,10 +279,11 @@ async def PartitionsFn( self, request: _empty_pb2.Empty, context: NumaflowServicerContext ) -> source_pb2.PartitionsResponse: """ - PartitionsFn returns the partitions of the user defined source. + PartitionsFn returns the active partitions and total partitions of the user defined source. """ try: - partitions = await self.__source_partitions_handler() + partitions = await self.__source_active_partitions_handler() + total_partitions = await self.__source_total_partitions_handler() except asyncio.CancelledError: # Task cancelled during shutdown (e.g. SIGTERM) — not a UDF fault. _LOGGER.info("Server shutting down, cancelling RPC.") @@ -301,8 +303,10 @@ async def PartitionsFn( return source_pb2.PartitionsResponse( result=source_pb2.PartitionsResponse.Result(partitions=[]) ) - resp = source_pb2.PartitionsResponse.Result(partitions=partitions.partitions) - return source_pb2.PartitionsResponse(result=resp) + result = source_pb2.PartitionsResponse.Result(partitions=partitions.partitions) + if total_partitions is not None: + result.total_partitions = total_partitions + return source_pb2.PartitionsResponse(result=result) def clean_background(self, task): """ diff --git a/packages/pynumaflow/tests/source/test_async_source.py b/packages/pynumaflow/tests/source/test_async_source.py index 00c8c0d4..abc7abb2 100644 --- a/packages/pynumaflow/tests/source/test_async_source.py +++ b/packages/pynumaflow/tests/source/test_async_source.py @@ -17,6 +17,7 @@ ack_req_source_fn, mock_partitions, AsyncSource, + AsyncSourceWithTotalPartitions, mock_offset, nack_req_source_fn, ) @@ -194,6 +195,61 @@ def test_partitions(async_source_server) -> None: assert response.result.partitions == mock_partitions() +def test_partitions_default_total_partitions_is_none(async_source_server) -> None: + """Verify total_partitions is not set when the source doesn't override total_partitions_handler.""" + with grpc.insecure_channel(server_port) as channel: + stub = source_pb2_grpc.SourceStub(channel) + request = _empty_pb2.Empty() + response = stub.PartitionsFn(request=request) + + assert response.result.partitions == mock_partitions() + assert not response.result.HasField("total_partitions") + + +server_port_tp = "unix:///tmp/async_source_tp.sock" + + +def NewAsyncSourcerWithTotalPartitions(): + class_instance = AsyncSourceWithTotalPartitions() + server = SourceAsyncServer(sourcer_instance=class_instance) + udfs = server.servicer + return udfs + + +async def start_server_tp(udfs): + server = grpc.aio.server() + source_pb2_grpc.add_SourceServicer_to_server(udfs, server) + listen_addr = server_port_tp + server.add_insecure_port(listen_addr) + logging.info("Starting server on %s", listen_addr) + await server.start() + return server, listen_addr + + +@pytest.fixture(scope="module") +def async_source_server_with_total_partitions(): + """Module-scoped fixture: starts an async gRPC source server with total partitions.""" + loop = create_async_loop() + + udfs = NewAsyncSourcerWithTotalPartitions() + server = start_async_server(loop, start_server_tp(udfs)) + + yield loop + + teardown_async_server(loop, server) + + +def test_partitions_with_total_partitions(async_source_server_with_total_partitions) -> None: + """Verify total_partitions flows through gRPC when the source implements total_partitions_handler.""" + with grpc.insecure_channel(server_port_tp) as channel: + stub = source_pb2_grpc.SourceStub(channel) + request = _empty_pb2.Empty() + response = stub.PartitionsFn(request=request) + + assert response.result.partitions == mock_partitions() + assert response.result.total_partitions == 10 + + @pytest.mark.parametrize( "max_threads_arg,expected", [ diff --git a/packages/pynumaflow/tests/source/utils.py b/packages/pynumaflow/tests/source/utils.py index 04daaa61..ece90815 100644 --- a/packages/pynumaflow/tests/source/utils.py +++ b/packages/pynumaflow/tests/source/utils.py @@ -56,6 +56,40 @@ async def partitions_handler(self) -> PartitionsResponse: return PartitionsResponse(partitions=mock_partitions()) +class AsyncSourceWithTotalPartitions(Sourcer): + """A test source that implements active_partitions_handler and total_partitions_handler.""" + + async def read_handler(self, datum: ReadRequest, output: NonBlockingIterator): + payload = b"payload:test_mock_message" + keys = ["test_key"] + offset = mock_offset() + event_time = mock_event_time() + for i in range(10): + await output.put( + Message( + payload=payload, + keys=keys, + offset=offset, + event_time=event_time, + ) + ) + + async def ack_handler(self, ack_request: AckRequest): + return + + async def nack_handler(self, nack_request: NackRequest): + return + + async def pending_handler(self) -> PendingResponse: + return PendingResponse(count=10) + + async def active_partitions_handler(self) -> PartitionsResponse: + return PartitionsResponse(partitions=mock_partitions()) + + async def total_partitions_handler(self) -> int | None: + return 10 + + class SyncSource(Sourcer): def read_handler(self, datum: ReadRequest) -> Iterable[Message]: payload = b"payload:test_mock_message" From b45fb483aa36edfb16f9cf6af8abbc2e5e593402 Mon Sep 17 00:00:00 2001 From: Vaibhav Tiwari Date: Thu, 26 Mar 2026 19:28:56 -0400 Subject: [PATCH 02/14] chore: fix linting Signed-off-by: Vaibhav Tiwari --- packages/pynumaflow/tests/source/test_async_source.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/pynumaflow/tests/source/test_async_source.py b/packages/pynumaflow/tests/source/test_async_source.py index abc7abb2..c4b4ec46 100644 --- a/packages/pynumaflow/tests/source/test_async_source.py +++ b/packages/pynumaflow/tests/source/test_async_source.py @@ -196,7 +196,10 @@ def test_partitions(async_source_server) -> None: def test_partitions_default_total_partitions_is_none(async_source_server) -> None: - """Verify total_partitions is not set when the source doesn't override total_partitions_handler.""" + """ + Verify total_partitions is not set when the source doesn't override + total_partitions_handler. + """ with grpc.insecure_channel(server_port) as channel: stub = source_pb2_grpc.SourceStub(channel) request = _empty_pb2.Empty() @@ -240,7 +243,9 @@ def async_source_server_with_total_partitions(): def test_partitions_with_total_partitions(async_source_server_with_total_partitions) -> None: - """Verify total_partitions flows through gRPC when the source implements total_partitions_handler.""" + """ + Verify total_partitions flows through gRPC when the source implements total_partitions_handler. + """ with grpc.insecure_channel(server_port_tp) as channel: stub = source_pb2_grpc.SourceStub(channel) request = _empty_pb2.Empty() From 68ad01c51330486b92d0e0d3350b41569f3c8d0d Mon Sep 17 00:00:00 2001 From: Vaibhav Tiwari Date: Fri, 27 Mar 2026 10:25:55 -0400 Subject: [PATCH 03/14] chore: Update example to use active_partitions_handler Signed-off-by: Vaibhav Tiwari --- packages/pynumaflow/examples/source/simple_source/example.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pynumaflow/examples/source/simple_source/example.py b/packages/pynumaflow/examples/source/simple_source/example.py index 56a1f785..802f3d1f 100644 --- a/packages/pynumaflow/examples/source/simple_source/example.py +++ b/packages/pynumaflow/examples/source/simple_source/example.py @@ -90,7 +90,7 @@ async def pending_handler(self) -> PendingResponse: """ return PendingResponse(count=0) - async def partitions_handler(self) -> PartitionsResponse: + async def active_partitions_handler(self) -> PartitionsResponse: """ The simple source always returns default partitions. """ From 9ecfa779c389012ca47701cc39a9d1e480c39b93 Mon Sep 17 00:00:00 2001 From: Vaibhav Tiwari Date: Fri, 27 Mar 2026 11:00:15 -0400 Subject: [PATCH 04/14] chore: Revert grpcio version to 1.75.0. Regenerate proto files with this version Signed-off-by: Vaibhav Tiwari --- .../proto/accumulator/accumulator_pb2_grpc.py | 4 +- .../proto/common/metadata_pb2_grpc.py | 4 +- .../pynumaflow/proto/mapper/map_pb2_grpc.py | 4 +- .../proto/reducer/reduce_pb2_grpc.py | 4 +- .../proto/sideinput/sideinput_pb2_grpc.py | 4 +- .../pynumaflow/proto/sinker/sink_pb2_grpc.py | 4 +- .../proto/sourcer/source_pb2_grpc.py | 4 +- .../sourcetransformer/transform_pb2_grpc.py | 4 +- packages/pynumaflow/uv.lock | 205 ++++++++---------- 9 files changed, 109 insertions(+), 128 deletions(-) diff --git a/packages/pynumaflow/pynumaflow/proto/accumulator/accumulator_pb2_grpc.py b/packages/pynumaflow/pynumaflow/proto/accumulator/accumulator_pb2_grpc.py index a7ad3972..e8a6e86d 100644 --- a/packages/pynumaflow/pynumaflow/proto/accumulator/accumulator_pb2_grpc.py +++ b/packages/pynumaflow/pynumaflow/proto/accumulator/accumulator_pb2_grpc.py @@ -6,7 +6,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from pynumaflow.proto.accumulator import accumulator_pb2 as pynumaflow_dot_proto_dot_accumulator_dot_accumulator__pb2 -GRPC_GENERATED_VERSION = '1.78.0' +GRPC_GENERATED_VERSION = '1.75.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -19,7 +19,7 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + ' but the generated code in pynumaflow/proto/accumulator/accumulator_pb2_grpc.py depends on' + + f' but the generated code in pynumaflow/proto/accumulator/accumulator_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' diff --git a/packages/pynumaflow/pynumaflow/proto/common/metadata_pb2_grpc.py b/packages/pynumaflow/pynumaflow/proto/common/metadata_pb2_grpc.py index 9691c0c4..2e60d47a 100644 --- a/packages/pynumaflow/pynumaflow/proto/common/metadata_pb2_grpc.py +++ b/packages/pynumaflow/pynumaflow/proto/common/metadata_pb2_grpc.py @@ -4,7 +4,7 @@ import warnings -GRPC_GENERATED_VERSION = '1.78.0' +GRPC_GENERATED_VERSION = '1.75.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -17,7 +17,7 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + ' but the generated code in pynumaflow/proto/common/metadata_pb2_grpc.py depends on' + + f' but the generated code in pynumaflow/proto/common/metadata_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' diff --git a/packages/pynumaflow/pynumaflow/proto/mapper/map_pb2_grpc.py b/packages/pynumaflow/pynumaflow/proto/mapper/map_pb2_grpc.py index cf4a2d11..7325b904 100644 --- a/packages/pynumaflow/pynumaflow/proto/mapper/map_pb2_grpc.py +++ b/packages/pynumaflow/pynumaflow/proto/mapper/map_pb2_grpc.py @@ -6,7 +6,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from pynumaflow.proto.mapper import map_pb2 as pynumaflow_dot_proto_dot_mapper_dot_map__pb2 -GRPC_GENERATED_VERSION = '1.78.0' +GRPC_GENERATED_VERSION = '1.75.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -19,7 +19,7 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + ' but the generated code in pynumaflow/proto/mapper/map_pb2_grpc.py depends on' + + f' but the generated code in pynumaflow/proto/mapper/map_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' diff --git a/packages/pynumaflow/pynumaflow/proto/reducer/reduce_pb2_grpc.py b/packages/pynumaflow/pynumaflow/proto/reducer/reduce_pb2_grpc.py index 88a589dc..4a8dd390 100644 --- a/packages/pynumaflow/pynumaflow/proto/reducer/reduce_pb2_grpc.py +++ b/packages/pynumaflow/pynumaflow/proto/reducer/reduce_pb2_grpc.py @@ -6,7 +6,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from pynumaflow.proto.reducer import reduce_pb2 as pynumaflow_dot_proto_dot_reducer_dot_reduce__pb2 -GRPC_GENERATED_VERSION = '1.78.0' +GRPC_GENERATED_VERSION = '1.75.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -19,7 +19,7 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + ' but the generated code in pynumaflow/proto/reducer/reduce_pb2_grpc.py depends on' + + f' but the generated code in pynumaflow/proto/reducer/reduce_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' diff --git a/packages/pynumaflow/pynumaflow/proto/sideinput/sideinput_pb2_grpc.py b/packages/pynumaflow/pynumaflow/proto/sideinput/sideinput_pb2_grpc.py index a34c0e47..2f1c8203 100644 --- a/packages/pynumaflow/pynumaflow/proto/sideinput/sideinput_pb2_grpc.py +++ b/packages/pynumaflow/pynumaflow/proto/sideinput/sideinput_pb2_grpc.py @@ -6,7 +6,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from pynumaflow.proto.sideinput import sideinput_pb2 as pynumaflow_dot_proto_dot_sideinput_dot_sideinput__pb2 -GRPC_GENERATED_VERSION = '1.78.0' +GRPC_GENERATED_VERSION = '1.75.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -19,7 +19,7 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + ' but the generated code in pynumaflow/proto/sideinput/sideinput_pb2_grpc.py depends on' + + f' but the generated code in pynumaflow/proto/sideinput/sideinput_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' diff --git a/packages/pynumaflow/pynumaflow/proto/sinker/sink_pb2_grpc.py b/packages/pynumaflow/pynumaflow/proto/sinker/sink_pb2_grpc.py index 010b5352..cecd2790 100644 --- a/packages/pynumaflow/pynumaflow/proto/sinker/sink_pb2_grpc.py +++ b/packages/pynumaflow/pynumaflow/proto/sinker/sink_pb2_grpc.py @@ -6,7 +6,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from pynumaflow.proto.sinker import sink_pb2 as pynumaflow_dot_proto_dot_sinker_dot_sink__pb2 -GRPC_GENERATED_VERSION = '1.78.0' +GRPC_GENERATED_VERSION = '1.75.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -19,7 +19,7 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + ' but the generated code in pynumaflow/proto/sinker/sink_pb2_grpc.py depends on' + + f' but the generated code in pynumaflow/proto/sinker/sink_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' diff --git a/packages/pynumaflow/pynumaflow/proto/sourcer/source_pb2_grpc.py b/packages/pynumaflow/pynumaflow/proto/sourcer/source_pb2_grpc.py index 0fd4fb05..6dd4103d 100644 --- a/packages/pynumaflow/pynumaflow/proto/sourcer/source_pb2_grpc.py +++ b/packages/pynumaflow/pynumaflow/proto/sourcer/source_pb2_grpc.py @@ -6,7 +6,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from pynumaflow.proto.sourcer import source_pb2 as pynumaflow_dot_proto_dot_sourcer_dot_source__pb2 -GRPC_GENERATED_VERSION = '1.78.0' +GRPC_GENERATED_VERSION = '1.75.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -19,7 +19,7 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + ' but the generated code in pynumaflow/proto/sourcer/source_pb2_grpc.py depends on' + + f' but the generated code in pynumaflow/proto/sourcer/source_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' diff --git a/packages/pynumaflow/pynumaflow/proto/sourcetransformer/transform_pb2_grpc.py b/packages/pynumaflow/pynumaflow/proto/sourcetransformer/transform_pb2_grpc.py index 9ad98b7d..942c4450 100644 --- a/packages/pynumaflow/pynumaflow/proto/sourcetransformer/transform_pb2_grpc.py +++ b/packages/pynumaflow/pynumaflow/proto/sourcetransformer/transform_pb2_grpc.py @@ -6,7 +6,7 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 from pynumaflow.proto.sourcetransformer import transform_pb2 as pynumaflow_dot_proto_dot_sourcetransformer_dot_transform__pb2 -GRPC_GENERATED_VERSION = '1.78.0' +GRPC_GENERATED_VERSION = '1.75.0' GRPC_VERSION = grpc.__version__ _version_not_supported = False @@ -19,7 +19,7 @@ if _version_not_supported: raise RuntimeError( f'The grpc package installed is at version {GRPC_VERSION},' - + ' but the generated code in pynumaflow/proto/sourcetransformer/transform_pb2_grpc.py depends on' + + f' but the generated code in pynumaflow/proto/sourcetransformer/transform_pb2_grpc.py depends on' + f' grpcio>={GRPC_GENERATED_VERSION}.' + f' Please upgrade your grpc module to grpcio>={GRPC_GENERATED_VERSION}' + f' or downgrade your generated code using grpcio-tools<={GRPC_VERSION}.' diff --git a/packages/pynumaflow/uv.lock b/packages/pynumaflow/uv.lock index 5fad94fd..3aea0d0b 100644 --- a/packages/pynumaflow/uv.lock +++ b/packages/pynumaflow/uv.lock @@ -623,6 +623,7 @@ wheels = [ name = "griffelib" version = "2.0.0" source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ad/06/eccbd311c9e2b3ca45dbc063b93134c57a1ccc7607c5e545264ad092c4a9/griffelib-2.0.0.tar.gz", hash = "sha256:e504d637a089f5cab9b5daf18f7645970509bf4f53eda8d79ed71cce8bd97934", size = 166312, upload-time = "2026-03-23T21:06:55.954Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/4d/51/c936033e16d12b627ea334aaaaf42229c37620d0f15593456ab69ab48161/griffelib-2.0.0-py3-none-any.whl", hash = "sha256:01284878c966508b6d6f1dbff9b6fa607bc062d8261c5c7253cb285b06422a7f", size = 142004, upload-time = "2026-02-09T19:09:40.561Z" }, ] @@ -641,153 +642,133 @@ wheels = [ [[package]] name = "grpcio" -version = "1.78.0" +version = "1.75.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/06/8a/3d098f35c143a89520e568e6539cc098fcd294495910e359889ce8741c84/grpcio-1.78.0.tar.gz", hash = "sha256:7382b95189546f375c174f53a5fa873cef91c4b8005faa05cc5b3beea9c4f1c5", size = 12852416, upload-time = "2026-02-06T09:57:18.093Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/a8/690a085b4d1fe066130de97a87de32c45062cf2ecd218df9675add895550/grpcio-1.78.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:7cc47943d524ee0096f973e1081cb8f4f17a4615f2116882a5f1416e4cfe92b5", size = 5946986, upload-time = "2026-02-06T09:54:34.043Z" }, - { url = "https://files.pythonhosted.org/packages/c7/1b/e5213c5c0ced9d2d92778d30529ad5bb2dcfb6c48c4e2d01b1f302d33d64/grpcio-1.78.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:c3f293fdc675ccba4db5a561048cca627b5e7bd1c8a6973ffedabe7d116e22e2", size = 11816533, upload-time = "2026-02-06T09:54:37.04Z" }, - { url = "https://files.pythonhosted.org/packages/18/37/1ba32dccf0a324cc5ace744c44331e300b000a924bf14840f948c559ede7/grpcio-1.78.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:10a9a644b5dd5aec3b82b5b0b90d41c0fa94c85ef42cb42cf78a23291ddb5e7d", size = 6519964, upload-time = "2026-02-06T09:54:40.268Z" }, - { url = "https://files.pythonhosted.org/packages/ed/f5/c0e178721b818072f2e8b6fde13faaba942406c634009caf065121ce246b/grpcio-1.78.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:4c5533d03a6cbd7f56acfc9cfb44ea64f63d29091e40e44010d34178d392d7eb", size = 7198058, upload-time = "2026-02-06T09:54:42.389Z" }, - { url = "https://files.pythonhosted.org/packages/5b/b2/40d43c91ae9cd667edc960135f9f08e58faa1576dc95af29f66ec912985f/grpcio-1.78.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ff870aebe9a93a85283837801d35cd5f8814fe2ad01e606861a7fb47c762a2b7", size = 6727212, upload-time = "2026-02-06T09:54:44.91Z" }, - { url = "https://files.pythonhosted.org/packages/ed/88/9da42eed498f0efcfcd9156e48ae63c0cde3bea398a16c99fb5198c885b6/grpcio-1.78.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:391e93548644e6b2726f1bb84ed60048d4bcc424ce5e4af0843d28ca0b754fec", size = 7300845, upload-time = "2026-02-06T09:54:47.562Z" }, - { url = "https://files.pythonhosted.org/packages/23/3f/1c66b7b1b19a8828890e37868411a6e6925df5a9030bfa87ab318f34095d/grpcio-1.78.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:df2c8f3141f7cbd112a6ebbd760290b5849cda01884554f7c67acc14e7b1758a", size = 8284605, upload-time = "2026-02-06T09:54:50.475Z" }, - { url = "https://files.pythonhosted.org/packages/94/c4/ca1bd87394f7b033e88525384b4d1e269e8424ab441ea2fba1a0c5b50986/grpcio-1.78.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bd8cb8026e5f5b50498a3c4f196f57f9db344dad829ffae16b82e4fdbaea2813", size = 7726672, upload-time = "2026-02-06T09:54:53.11Z" }, - { url = "https://files.pythonhosted.org/packages/41/09/f16e487d4cc65ccaf670f6ebdd1a17566b965c74fc3d93999d3b2821e052/grpcio-1.78.0-cp310-cp310-win32.whl", hash = "sha256:f8dff3d9777e5d2703a962ee5c286c239bf0ba173877cc68dc02c17d042e29de", size = 4076715, upload-time = "2026-02-06T09:54:55.549Z" }, - { url = "https://files.pythonhosted.org/packages/2a/32/4ce60d94e242725fd3bcc5673c04502c82a8e87b21ea411a63992dc39f8f/grpcio-1.78.0-cp310-cp310-win_amd64.whl", hash = "sha256:94f95cf5d532d0e717eed4fc1810e8e6eded04621342ec54c89a7c2f14b581bf", size = 4799157, upload-time = "2026-02-06T09:54:59.838Z" }, - { url = "https://files.pythonhosted.org/packages/86/c7/d0b780a29b0837bf4ca9580904dfb275c1fc321ded7897d620af7047ec57/grpcio-1.78.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:2777b783f6c13b92bd7b716667452c329eefd646bfb3f2e9dabea2e05dbd34f6", size = 5951525, upload-time = "2026-02-06T09:55:01.989Z" }, - { url = "https://files.pythonhosted.org/packages/c5/b1/96920bf2ee61df85a9503cb6f733fe711c0ff321a5a697d791b075673281/grpcio-1.78.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:9dca934f24c732750389ce49d638069c3892ad065df86cb465b3fa3012b70c9e", size = 11830418, upload-time = "2026-02-06T09:55:04.462Z" }, - { url = "https://files.pythonhosted.org/packages/83/0c/7c1528f098aeb75a97de2bae18c530f56959fb7ad6c882db45d9884d6edc/grpcio-1.78.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:459ab414b35f4496138d0ecd735fed26f1318af5e52cb1efbc82a09f0d5aa911", size = 6524477, upload-time = "2026-02-06T09:55:07.111Z" }, - { url = "https://files.pythonhosted.org/packages/8d/52/e7c1f3688f949058e19a011c4e0dec973da3d0ae5e033909677f967ae1f4/grpcio-1.78.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:082653eecbdf290e6e3e2c276ab2c54b9e7c299e07f4221872380312d8cf395e", size = 7198266, upload-time = "2026-02-06T09:55:10.016Z" }, - { url = "https://files.pythonhosted.org/packages/e5/61/8ac32517c1e856677282c34f2e7812d6c328fa02b8f4067ab80e77fdc9c9/grpcio-1.78.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:85f93781028ec63f383f6bc90db785a016319c561cc11151fbb7b34e0d012303", size = 6730552, upload-time = "2026-02-06T09:55:12.207Z" }, - { url = "https://files.pythonhosted.org/packages/bd/98/b8ee0158199250220734f620b12e4a345955ac7329cfd908d0bf0fda77f0/grpcio-1.78.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f12857d24d98441af6a1d5c87442d624411db486f7ba12550b07788f74b67b04", size = 7304296, upload-time = "2026-02-06T09:55:15.044Z" }, - { url = "https://files.pythonhosted.org/packages/bd/0f/7b72762e0d8840b58032a56fdbd02b78fc645b9fa993d71abf04edbc54f4/grpcio-1.78.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5397fff416b79e4b284959642a4e95ac4b0f1ece82c9993658e0e477d40551ec", size = 8288298, upload-time = "2026-02-06T09:55:17.276Z" }, - { url = "https://files.pythonhosted.org/packages/24/ae/ae4ce56bc5bb5caa3a486d60f5f6083ac3469228faa734362487176c15c5/grpcio-1.78.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:fbe6e89c7ffb48518384068321621b2a69cab509f58e40e4399fdd378fa6d074", size = 7730953, upload-time = "2026-02-06T09:55:19.545Z" }, - { url = "https://files.pythonhosted.org/packages/b5/6e/8052e3a28eb6a820c372b2eb4b5e32d195c661e137d3eca94d534a4cfd8a/grpcio-1.78.0-cp311-cp311-win32.whl", hash = "sha256:6092beabe1966a3229f599d7088b38dfc8ffa1608b5b5cdda31e591e6500f856", size = 4076503, upload-time = "2026-02-06T09:55:21.521Z" }, - { url = "https://files.pythonhosted.org/packages/08/62/f22c98c5265dfad327251fa2f840b591b1df5f5e15d88b19c18c86965b27/grpcio-1.78.0-cp311-cp311-win_amd64.whl", hash = "sha256:1afa62af6e23f88629f2b29ec9e52ec7c65a7176c1e0a83292b93c76ca882558", size = 4799767, upload-time = "2026-02-06T09:55:24.107Z" }, - { url = "https://files.pythonhosted.org/packages/4e/f4/7384ed0178203d6074446b3c4f46c90a22ddf7ae0b3aee521627f54cfc2a/grpcio-1.78.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:f9ab915a267fc47c7e88c387a3a28325b58c898e23d4995f765728f4e3dedb97", size = 5913985, upload-time = "2026-02-06T09:55:26.832Z" }, - { url = "https://files.pythonhosted.org/packages/81/ed/be1caa25f06594463f685b3790b320f18aea49b33166f4141bfdc2bfb236/grpcio-1.78.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3f8904a8165ab21e07e58bf3e30a73f4dffc7a1e0dbc32d51c61b5360d26f43e", size = 11811853, upload-time = "2026-02-06T09:55:29.224Z" }, - { url = "https://files.pythonhosted.org/packages/24/a7/f06d151afc4e64b7e3cc3e872d331d011c279aaab02831e40a81c691fb65/grpcio-1.78.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:859b13906ce098c0b493af92142ad051bf64c7870fa58a123911c88606714996", size = 6475766, upload-time = "2026-02-06T09:55:31.825Z" }, - { url = "https://files.pythonhosted.org/packages/8a/a8/4482922da832ec0082d0f2cc3a10976d84a7424707f25780b82814aafc0a/grpcio-1.78.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:b2342d87af32790f934a79c3112641e7b27d63c261b8b4395350dad43eff1dc7", size = 7170027, upload-time = "2026-02-06T09:55:34.7Z" }, - { url = "https://files.pythonhosted.org/packages/54/bf/f4a3b9693e35d25b24b0b39fa46d7d8a3c439e0a3036c3451764678fec20/grpcio-1.78.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:12a771591ae40bc65ba67048fa52ef4f0e6db8279e595fd349f9dfddeef571f9", size = 6690766, upload-time = "2026-02-06T09:55:36.902Z" }, - { url = "https://files.pythonhosted.org/packages/c7/b9/521875265cc99fe5ad4c5a17010018085cae2810a928bf15ebe7d8bcd9cc/grpcio-1.78.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:185dea0d5260cbb2d224c507bf2a5444d5abbb1fa3594c1ed7e4c709d5eb8383", size = 7266161, upload-time = "2026-02-06T09:55:39.824Z" }, - { url = "https://files.pythonhosted.org/packages/05/86/296a82844fd40a4ad4a95f100b55044b4f817dece732bf686aea1a284147/grpcio-1.78.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:51b13f9aed9d59ee389ad666b8c2214cc87b5de258fa712f9ab05f922e3896c6", size = 8253303, upload-time = "2026-02-06T09:55:42.353Z" }, - { url = "https://files.pythonhosted.org/packages/f3/e4/ea3c0caf5468537f27ad5aab92b681ed7cc0ef5f8c9196d3fd42c8c2286b/grpcio-1.78.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fd5f135b1bd58ab088930b3c613455796dfa0393626a6972663ccdda5b4ac6ce", size = 7698222, upload-time = "2026-02-06T09:55:44.629Z" }, - { url = "https://files.pythonhosted.org/packages/d7/47/7f05f81e4bb6b831e93271fb12fd52ba7b319b5402cbc101d588f435df00/grpcio-1.78.0-cp312-cp312-win32.whl", hash = "sha256:94309f498bcc07e5a7d16089ab984d42ad96af1d94b5a4eb966a266d9fcabf68", size = 4066123, upload-time = "2026-02-06T09:55:47.644Z" }, - { url = "https://files.pythonhosted.org/packages/ad/e7/d6914822c88aa2974dbbd10903d801a28a19ce9cd8bad7e694cbbcf61528/grpcio-1.78.0-cp312-cp312-win_amd64.whl", hash = "sha256:9566fe4ababbb2610c39190791e5b829869351d14369603702e890ef3ad2d06e", size = 4797657, upload-time = "2026-02-06T09:55:49.86Z" }, - { url = "https://files.pythonhosted.org/packages/05/a9/8f75894993895f361ed8636cd9237f4ab39ef87fd30db17467235ed1c045/grpcio-1.78.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:ce3a90455492bf8bfa38e56fbbe1dbd4f872a3d8eeaf7337dc3b1c8aa28c271b", size = 5920143, upload-time = "2026-02-06T09:55:52.035Z" }, - { url = "https://files.pythonhosted.org/packages/55/06/0b78408e938ac424100100fd081189451b472236e8a3a1f6500390dc4954/grpcio-1.78.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:2bf5e2e163b356978b23652c4818ce4759d40f4712ee9ec5a83c4be6f8c23a3a", size = 11803926, upload-time = "2026-02-06T09:55:55.494Z" }, - { url = "https://files.pythonhosted.org/packages/88/93/b59fe7832ff6ae3c78b813ea43dac60e295fa03606d14d89d2e0ec29f4f3/grpcio-1.78.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8f2ac84905d12918e4e55a16da17939eb63e433dc11b677267c35568aa63fc84", size = 6478628, upload-time = "2026-02-06T09:55:58.533Z" }, - { url = "https://files.pythonhosted.org/packages/ed/df/e67e3734527f9926b7d9c0dde6cd998d1d26850c3ed8eeec81297967ac67/grpcio-1.78.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:b58f37edab4a3881bc6c9bca52670610e0c9ca14e2ea3cf9debf185b870457fb", size = 7173574, upload-time = "2026-02-06T09:56:01.786Z" }, - { url = "https://files.pythonhosted.org/packages/a6/62/cc03fffb07bfba982a9ec097b164e8835546980aec25ecfa5f9c1a47e022/grpcio-1.78.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:735e38e176a88ce41840c21bb49098ab66177c64c82426e24e0082500cc68af5", size = 6692639, upload-time = "2026-02-06T09:56:04.529Z" }, - { url = "https://files.pythonhosted.org/packages/bf/9a/289c32e301b85bdb67d7ec68b752155e674ee3ba2173a1858f118e399ef3/grpcio-1.78.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2045397e63a7a0ee7957c25f7dbb36ddc110e0cfb418403d110c0a7a68a844e9", size = 7268838, upload-time = "2026-02-06T09:56:08.397Z" }, - { url = "https://files.pythonhosted.org/packages/0e/79/1be93f32add280461fa4773880196572563e9c8510861ac2da0ea0f892b6/grpcio-1.78.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a9f136fbafe7ccf4ac7e8e0c28b31066e810be52d6e344ef954a3a70234e1702", size = 8251878, upload-time = "2026-02-06T09:56:10.914Z" }, - { url = "https://files.pythonhosted.org/packages/65/65/793f8e95296ab92e4164593674ae6291b204bb5f67f9d4a711489cd30ffa/grpcio-1.78.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:748b6138585379c737adc08aeffd21222abbda1a86a0dca2a39682feb9196c20", size = 7695412, upload-time = "2026-02-06T09:56:13.593Z" }, - { url = "https://files.pythonhosted.org/packages/1c/9f/1e233fe697ecc82845942c2822ed06bb522e70d6771c28d5528e4c50f6a4/grpcio-1.78.0-cp313-cp313-win32.whl", hash = "sha256:271c73e6e5676afe4fc52907686670c7cea22ab2310b76a59b678403ed40d670", size = 4064899, upload-time = "2026-02-06T09:56:15.601Z" }, - { url = "https://files.pythonhosted.org/packages/4d/27/d86b89e36de8a951501fb06a0f38df19853210f341d0b28f83f4aa0ffa08/grpcio-1.78.0-cp313-cp313-win_amd64.whl", hash = "sha256:f2d4e43ee362adfc05994ed479334d5a451ab7bc3f3fee1b796b8ca66895acb4", size = 4797393, upload-time = "2026-02-06T09:56:17.882Z" }, - { url = "https://files.pythonhosted.org/packages/29/f2/b56e43e3c968bfe822fa6ce5bca10d5c723aa40875b48791ce1029bb78c7/grpcio-1.78.0-cp314-cp314-linux_armv7l.whl", hash = "sha256:e87cbc002b6f440482b3519e36e1313eb5443e9e9e73d6a52d43bd2004fcfd8e", size = 5920591, upload-time = "2026-02-06T09:56:20.758Z" }, - { url = "https://files.pythonhosted.org/packages/5d/81/1f3b65bd30c334167bfa8b0d23300a44e2725ce39bba5b76a2460d85f745/grpcio-1.78.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:c41bc64626db62e72afec66b0c8a0da76491510015417c127bfc53b2fe6d7f7f", size = 11813685, upload-time = "2026-02-06T09:56:24.315Z" }, - { url = "https://files.pythonhosted.org/packages/0e/1c/bbe2f8216a5bd3036119c544d63c2e592bdf4a8ec6e4a1867592f4586b26/grpcio-1.78.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8dfffba826efcf366b1e3ccc37e67afe676f290e13a3b48d31a46739f80a8724", size = 6487803, upload-time = "2026-02-06T09:56:27.367Z" }, - { url = "https://files.pythonhosted.org/packages/16/5c/a6b2419723ea7ddce6308259a55e8e7593d88464ce8db9f4aa857aba96fa/grpcio-1.78.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:74be1268d1439eaaf552c698cdb11cd594f0c49295ae6bb72c34ee31abbe611b", size = 7173206, upload-time = "2026-02-06T09:56:29.876Z" }, - { url = "https://files.pythonhosted.org/packages/df/1e/b8801345629a415ea7e26c83d75eb5dbe91b07ffe5210cc517348a8d4218/grpcio-1.78.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be63c88b32e6c0f1429f1398ca5c09bc64b0d80950c8bb7807d7d7fb36fb84c7", size = 6693826, upload-time = "2026-02-06T09:56:32.305Z" }, - { url = "https://files.pythonhosted.org/packages/34/84/0de28eac0377742679a510784f049738a80424b17287739fc47d63c2439e/grpcio-1.78.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:3c586ac70e855c721bda8f548d38c3ca66ac791dc49b66a8281a1f99db85e452", size = 7277897, upload-time = "2026-02-06T09:56:34.915Z" }, - { url = "https://files.pythonhosted.org/packages/ca/9c/ad8685cfe20559a9edb66f735afdcb2b7d3de69b13666fdfc542e1916ebd/grpcio-1.78.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:35eb275bf1751d2ffbd8f57cdbc46058e857cf3971041521b78b7db94bdaf127", size = 8252404, upload-time = "2026-02-06T09:56:37.553Z" }, - { url = "https://files.pythonhosted.org/packages/3c/05/33a7a4985586f27e1de4803887c417ec7ced145ebd069bc38a9607059e2b/grpcio-1.78.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:207db540302c884b8848036b80db352a832b99dfdf41db1eb554c2c2c7800f65", size = 7696837, upload-time = "2026-02-06T09:56:40.173Z" }, - { url = "https://files.pythonhosted.org/packages/73/77/7382241caf88729b106e49e7d18e3116216c778e6a7e833826eb96de22f7/grpcio-1.78.0-cp314-cp314-win32.whl", hash = "sha256:57bab6deef2f4f1ca76cc04565df38dc5713ae6c17de690721bdf30cb1e0545c", size = 4142439, upload-time = "2026-02-06T09:56:43.258Z" }, - { url = "https://files.pythonhosted.org/packages/48/b2/b096ccce418882fbfda4f7496f9357aaa9a5af1896a9a7f60d9f2b275a06/grpcio-1.78.0-cp314-cp314-win_amd64.whl", hash = "sha256:dce09d6116df20a96acfdbf85e4866258c3758180e8c49845d6ba8248b6d0bbb", size = 4929852, upload-time = "2026-02-06T09:56:45.885Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/91/88/fe2844eefd3d2188bc0d7a2768c6375b46dfd96469ea52d8aeee8587d7e0/grpcio-1.75.0.tar.gz", hash = "sha256:b989e8b09489478c2d19fecc744a298930f40d8b27c3638afbfe84d22f36ce4e", size = 12722485, upload-time = "2025-09-16T09:20:21.731Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/90/91f780f6cb8b2aa1bc8b8f8561a4e9d3bfe5dea10a4532843f2b044e18ac/grpcio-1.75.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:1ec9cbaec18d9597c718b1ed452e61748ac0b36ba350d558f9ded1a94cc15ec7", size = 5696373, upload-time = "2025-09-16T09:18:07.971Z" }, + { url = "https://files.pythonhosted.org/packages/fc/c6/eaf9065ff15d0994e1674e71e1ca9542ee47f832b4df0fde1b35e5641fa1/grpcio-1.75.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:7ee5ee42bfae8238b66a275f9ebcf6f295724375f2fa6f3b52188008b6380faf", size = 11465905, upload-time = "2025-09-16T09:18:12.383Z" }, + { url = "https://files.pythonhosted.org/packages/8a/21/ae33e514cb7c3f936b378d1c7aab6d8e986814b3489500c5cc860c48ce88/grpcio-1.75.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9146e40378f551eed66c887332afc807fcce593c43c698e21266a4227d4e20d2", size = 6282149, upload-time = "2025-09-16T09:18:15.427Z" }, + { url = "https://files.pythonhosted.org/packages/d5/46/dff6344e6f3e81707bc87bba796592036606aca04b6e9b79ceec51902b80/grpcio-1.75.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:0c40f368541945bb664857ecd7400acb901053a1abbcf9f7896361b2cfa66798", size = 6940277, upload-time = "2025-09-16T09:18:17.564Z" }, + { url = "https://files.pythonhosted.org/packages/9a/5f/e52cb2c16e097d950c36e7bb2ef46a3b2e4c7ae6b37acb57d88538182b85/grpcio-1.75.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:50a6e43a9adc6938e2a16c9d9f8a2da9dd557ddd9284b73b07bd03d0e098d1e9", size = 6460422, upload-time = "2025-09-16T09:18:19.657Z" }, + { url = "https://files.pythonhosted.org/packages/fd/16/527533f0bd9cace7cd800b7dae903e273cc987fc472a398a4bb6747fec9b/grpcio-1.75.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dce15597ca11913b78e1203c042d5723e3ea7f59e7095a1abd0621be0e05b895", size = 7089969, upload-time = "2025-09-16T09:18:21.73Z" }, + { url = "https://files.pythonhosted.org/packages/88/4f/1d448820bc88a2be7045aac817a59ba06870e1ebad7ed19525af7ac079e7/grpcio-1.75.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:851194eec47755101962da423f575ea223c9dd7f487828fe5693920e8745227e", size = 8033548, upload-time = "2025-09-16T09:18:23.819Z" }, + { url = "https://files.pythonhosted.org/packages/37/00/19e87ab12c8b0d73a252eef48664030de198514a4e30bdf337fa58bcd4dd/grpcio-1.75.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ca123db0813eef80625a4242a0c37563cb30a3edddebe5ee65373854cf187215", size = 7487161, upload-time = "2025-09-16T09:18:25.934Z" }, + { url = "https://files.pythonhosted.org/packages/37/d0/f7b9deaa6ccca9997fa70b4e143cf976eaec9476ecf4d05f7440ac400635/grpcio-1.75.0-cp310-cp310-win32.whl", hash = "sha256:222b0851e20c04900c63f60153503e918b08a5a0fad8198401c0b1be13c6815b", size = 3946254, upload-time = "2025-09-16T09:18:28.42Z" }, + { url = "https://files.pythonhosted.org/packages/6d/42/8d04744c7dc720cc9805a27f879cbf7043bb5c78dce972f6afb8613860de/grpcio-1.75.0-cp310-cp310-win_amd64.whl", hash = "sha256:bb58e38a50baed9b21492c4b3f3263462e4e37270b7ea152fc10124b4bd1c318", size = 4640072, upload-time = "2025-09-16T09:18:30.426Z" }, + { url = "https://files.pythonhosted.org/packages/95/b7/a6f42596fc367656970f5811e5d2d9912ca937aa90621d5468a11680ef47/grpcio-1.75.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:7f89d6d0cd43170a80ebb4605cad54c7d462d21dc054f47688912e8bf08164af", size = 5699769, upload-time = "2025-09-16T09:18:32.536Z" }, + { url = "https://files.pythonhosted.org/packages/c2/42/284c463a311cd2c5f804fd4fdbd418805460bd5d702359148dd062c1685d/grpcio-1.75.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:cb6c5b075c2d092f81138646a755f0dad94e4622300ebef089f94e6308155d82", size = 11480362, upload-time = "2025-09-16T09:18:35.562Z" }, + { url = "https://files.pythonhosted.org/packages/0b/10/60d54d5a03062c3ae91bddb6e3acefe71264307a419885f453526d9203ff/grpcio-1.75.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:494dcbade5606128cb9f530ce00331a90ecf5e7c5b243d373aebdb18e503c346", size = 6284753, upload-time = "2025-09-16T09:18:38.055Z" }, + { url = "https://files.pythonhosted.org/packages/cf/af/381a4bfb04de5e2527819452583e694df075c7a931e9bf1b2a603b593ab2/grpcio-1.75.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:050760fd29c8508844a720f06c5827bb00de8f5e02f58587eb21a4444ad706e5", size = 6944103, upload-time = "2025-09-16T09:18:40.844Z" }, + { url = "https://files.pythonhosted.org/packages/16/18/c80dd7e1828bd6700ce242c1616871927eef933ed0c2cee5c636a880e47b/grpcio-1.75.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:266fa6209b68a537b2728bb2552f970e7e78c77fe43c6e9cbbe1f476e9e5c35f", size = 6464036, upload-time = "2025-09-16T09:18:43.351Z" }, + { url = "https://files.pythonhosted.org/packages/79/3f/78520c7ed9ccea16d402530bc87958bbeb48c42a2ec8032738a7864d38f8/grpcio-1.75.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:06d22e1d8645e37bc110f4c589cb22c283fd3de76523065f821d6e81de33f5d4", size = 7097455, upload-time = "2025-09-16T09:18:45.465Z" }, + { url = "https://files.pythonhosted.org/packages/ad/69/3cebe4901a865eb07aefc3ee03a02a632e152e9198dadf482a7faf926f31/grpcio-1.75.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9880c323595d851292785966cadb6c708100b34b163cab114e3933f5773cba2d", size = 8037203, upload-time = "2025-09-16T09:18:47.878Z" }, + { url = "https://files.pythonhosted.org/packages/04/ed/1e483d1eba5032642c10caf28acf07ca8de0508244648947764956db346a/grpcio-1.75.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:55a2d5ae79cd0f68783fb6ec95509be23746e3c239290b2ee69c69a38daa961a", size = 7492085, upload-time = "2025-09-16T09:18:50.907Z" }, + { url = "https://files.pythonhosted.org/packages/ee/65/6ef676aa7dbd9578dfca990bb44d41a49a1e36344ca7d79de6b59733ba96/grpcio-1.75.0-cp311-cp311-win32.whl", hash = "sha256:352dbdf25495eef584c8de809db280582093bc3961d95a9d78f0dfb7274023a2", size = 3944697, upload-time = "2025-09-16T09:18:53.427Z" }, + { url = "https://files.pythonhosted.org/packages/0d/83/b753373098b81ec5cb01f71c21dfd7aafb5eb48a1566d503e9fd3c1254fe/grpcio-1.75.0-cp311-cp311-win_amd64.whl", hash = "sha256:678b649171f229fb16bda1a2473e820330aa3002500c4f9fd3a74b786578e90f", size = 4642235, upload-time = "2025-09-16T09:18:56.095Z" }, + { url = "https://files.pythonhosted.org/packages/0d/93/a1b29c2452d15cecc4a39700fbf54721a3341f2ddbd1bd883f8ec0004e6e/grpcio-1.75.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:fa35ccd9501ffdd82b861809cbfc4b5b13f4b4c5dc3434d2d9170b9ed38a9054", size = 5661861, upload-time = "2025-09-16T09:18:58.748Z" }, + { url = "https://files.pythonhosted.org/packages/b8/ce/7280df197e602d14594e61d1e60e89dfa734bb59a884ba86cdd39686aadb/grpcio-1.75.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:0fcb77f2d718c1e58cc04ef6d3b51e0fa3b26cf926446e86c7eba105727b6cd4", size = 11459982, upload-time = "2025-09-16T09:19:01.211Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9b/37e61349771f89b543a0a0bbc960741115ea8656a2414bfb24c4de6f3dd7/grpcio-1.75.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:36764a4ad9dc1eb891042fab51e8cdf7cc014ad82cee807c10796fb708455041", size = 6239680, upload-time = "2025-09-16T09:19:04.443Z" }, + { url = "https://files.pythonhosted.org/packages/a6/66/f645d9d5b22ca307f76e71abc83ab0e574b5dfef3ebde4ec8b865dd7e93e/grpcio-1.75.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:725e67c010f63ef17fc052b261004942763c0b18dcd84841e6578ddacf1f9d10", size = 6908511, upload-time = "2025-09-16T09:19:07.884Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9a/34b11cd62d03c01b99068e257595804c695c3c119596c7077f4923295e19/grpcio-1.75.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91fbfc43f605c5ee015c9056d580a70dd35df78a7bad97e05426795ceacdb59f", size = 6429105, upload-time = "2025-09-16T09:19:10.085Z" }, + { url = "https://files.pythonhosted.org/packages/1a/46/76eaceaad1f42c1e7e6a5b49a61aac40fc5c9bee4b14a1630f056ac3a57e/grpcio-1.75.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a9337ac4ce61c388e02019d27fa837496c4b7837cbbcec71b05934337e51531", size = 7060578, upload-time = "2025-09-16T09:19:12.283Z" }, + { url = "https://files.pythonhosted.org/packages/3d/82/181a0e3f1397b6d43239e95becbeb448563f236c0db11ce990f073b08d01/grpcio-1.75.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ee16e232e3d0974750ab5f4da0ab92b59d6473872690b5e40dcec9a22927f22e", size = 8003283, upload-time = "2025-09-16T09:19:15.601Z" }, + { url = "https://files.pythonhosted.org/packages/de/09/a335bca211f37a3239be4b485e3c12bf3da68d18b1f723affdff2b9e9680/grpcio-1.75.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:55dfb9122973cc69520b23d39867726722cafb32e541435707dc10249a1bdbc6", size = 7460319, upload-time = "2025-09-16T09:19:18.409Z" }, + { url = "https://files.pythonhosted.org/packages/aa/59/6330105cdd6bc4405e74c96838cd7e148c3653ae3996e540be6118220c79/grpcio-1.75.0-cp312-cp312-win32.whl", hash = "sha256:fb64dd62face3d687a7b56cd881e2ea39417af80f75e8b36f0f81dfd93071651", size = 3934011, upload-time = "2025-09-16T09:19:21.013Z" }, + { url = "https://files.pythonhosted.org/packages/ff/14/e1309a570b7ebdd1c8ca24c4df6b8d6690009fa8e0d997cb2c026ce850c9/grpcio-1.75.0-cp312-cp312-win_amd64.whl", hash = "sha256:6b365f37a9c9543a9e91c6b4103d68d38d5bcb9965b11d5092b3c157bd6a5ee7", size = 4637934, upload-time = "2025-09-16T09:19:23.19Z" }, + { url = "https://files.pythonhosted.org/packages/00/64/dbce0ffb6edaca2b292d90999dd32a3bd6bc24b5b77618ca28440525634d/grpcio-1.75.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:1bb78d052948d8272c820bb928753f16a614bb2c42fbf56ad56636991b427518", size = 5666860, upload-time = "2025-09-16T09:19:25.417Z" }, + { url = "https://files.pythonhosted.org/packages/f3/e6/da02c8fa882ad3a7f868d380bb3da2c24d35dd983dd12afdc6975907a352/grpcio-1.75.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:9dc4a02796394dd04de0b9673cb79a78901b90bb16bf99ed8cb528c61ed9372e", size = 11455148, upload-time = "2025-09-16T09:19:28.615Z" }, + { url = "https://files.pythonhosted.org/packages/ba/a0/84f87f6c2cf2a533cfce43b2b620eb53a51428ec0c8fe63e5dd21d167a70/grpcio-1.75.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:437eeb16091d31498585d73b133b825dc80a8db43311e332c08facf820d36894", size = 6243865, upload-time = "2025-09-16T09:19:31.342Z" }, + { url = "https://files.pythonhosted.org/packages/be/12/53da07aa701a4839dd70d16e61ce21ecfcc9e929058acb2f56e9b2dd8165/grpcio-1.75.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:c2c39984e846bd5da45c5f7bcea8fafbe47c98e1ff2b6f40e57921b0c23a52d0", size = 6915102, upload-time = "2025-09-16T09:19:33.658Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c0/7eaceafd31f52ec4bf128bbcf36993b4bc71f64480f3687992ddd1a6e315/grpcio-1.75.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:38d665f44b980acdbb2f0e1abf67605ba1899f4d2443908df9ec8a6f26d2ed88", size = 6432042, upload-time = "2025-09-16T09:19:36.583Z" }, + { url = "https://files.pythonhosted.org/packages/6b/12/a2ce89a9f4fc52a16ed92951f1b05f53c17c4028b3db6a4db7f08332bee8/grpcio-1.75.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2e8e752ab5cc0a9c5b949808c000ca7586223be4f877b729f034b912364c3964", size = 7062984, upload-time = "2025-09-16T09:19:39.163Z" }, + { url = "https://files.pythonhosted.org/packages/55/a6/2642a9b491e24482d5685c0f45c658c495a5499b43394846677abed2c966/grpcio-1.75.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3a6788b30aa8e6f207c417874effe3f79c2aa154e91e78e477c4825e8b431ce0", size = 8001212, upload-time = "2025-09-16T09:19:41.726Z" }, + { url = "https://files.pythonhosted.org/packages/19/20/530d4428750e9ed6ad4254f652b869a20a40a276c1f6817b8c12d561f5ef/grpcio-1.75.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc33e67cab6141c54e75d85acd5dec616c5095a957ff997b4330a6395aa9b51", size = 7457207, upload-time = "2025-09-16T09:19:44.368Z" }, + { url = "https://files.pythonhosted.org/packages/e2/6f/843670007e0790af332a21468d10059ea9fdf97557485ae633b88bd70efc/grpcio-1.75.0-cp313-cp313-win32.whl", hash = "sha256:c8cfc780b7a15e06253aae5f228e1e84c0d3c4daa90faf5bc26b751174da4bf9", size = 3934235, upload-time = "2025-09-16T09:19:46.815Z" }, + { url = "https://files.pythonhosted.org/packages/4b/92/c846b01b38fdf9e2646a682b12e30a70dc7c87dfe68bd5e009ee1501c14b/grpcio-1.75.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c91d5b16eff3cbbe76b7a1eaaf3d91e7a954501e9d4f915554f87c470475c3d", size = 4637558, upload-time = "2025-09-16T09:19:49.698Z" }, ] [[package]] name = "grpcio-status" -version = "1.78.0" +version = "1.75.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "googleapis-common-protos" }, { name = "grpcio" }, { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8a/cd/89ce482a931b543b92cdd9b2888805518c4620e0094409acb8c81dd4610a/grpcio_status-1.78.0.tar.gz", hash = "sha256:a34cfd28101bfea84b5aa0f936b4b423019e9213882907166af6b3bddc59e189", size = 13808, upload-time = "2026-02-06T10:01:48.034Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/8a/2e45ec0512d4ce9afa136c6e4186d063721b5b4c192eec7536ce6b7ba615/grpcio_status-1.75.0.tar.gz", hash = "sha256:69d5b91be1b8b926f086c1c483519a968c14640773a0ccdd6c04282515dbedf7", size = 13646, upload-time = "2025-09-16T09:24:51.069Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/83/8a/1241ec22c41028bddd4a052ae9369267b4475265ad0ce7140974548dc3fa/grpcio_status-1.78.0-py3-none-any.whl", hash = "sha256:b492b693d4bf27b47a6c32590701724f1d3b9444b36491878fb71f6208857f34", size = 14523, upload-time = "2026-02-06T10:01:32.584Z" }, + { url = "https://files.pythonhosted.org/packages/2b/24/d536f0a0fda3a3eeb334893e5fb9d567c2777de6a5384413f71b35cfd0e5/grpcio_status-1.75.0-py3-none-any.whl", hash = "sha256:de62557ef97b7e19c3ce6da19793a12c5f6c1fbbb918d233d9671aba9d9e1d78", size = 14424, upload-time = "2025-09-16T09:23:33.843Z" }, ] [[package]] name = "grpcio-testing" -version = "1.78.0" +version = "1.75.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "grpcio" }, { name = "protobuf" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ee/23/585947aabeb0c27224aa73103ff4f58b1500176f32440544375aff674041/grpcio_testing-1.78.0.tar.gz", hash = "sha256:06e42807be46949bdc88339a03a710ec055b06d6bc821cb596366e51659153cc", size = 23018, upload-time = "2026-02-06T10:01:53.249Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/65/3e42664b954b3a716a7a357c7ef54452fb70429afb634a5b8f40a46d314a/grpcio_testing-1.75.0.tar.gz", hash = "sha256:52e0c4f602faad000ae1afcf9d954377277eb7c9614cc5c9f82b290076c405bb", size = 22526, upload-time = "2025-09-16T09:24:52.938Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/59/b8/e37715198a4b05d80af3ce886c83f9658c0034a035706c60a36a0af053b2/grpcio_testing-1.78.0-py3-none-any.whl", hash = "sha256:2b018bc06e688f041f9bb47c26bfc4fb5ae4caf93b7b5f81442fcea2815a0085", size = 33319, upload-time = "2026-02-06T10:01:27.676Z" }, + { url = "https://files.pythonhosted.org/packages/53/79/fcdc5b505ebf4694820b66e2411cd428c3e63e9f21cfbf2c67c7baf678e9/grpcio_testing-1.75.0-py3-none-any.whl", hash = "sha256:ffe05ee52b0e6ca4e78b3e73d4e67c994346725d65301f4ebf718985c8b75422", size = 33218, upload-time = "2025-09-16T09:23:30.789Z" }, ] [[package]] name = "grpcio-tools" -version = "1.78.0" +version = "1.75.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "grpcio" }, { name = "protobuf" }, { name = "setuptools" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8b/d1/cbefe328653f746fd319c4377836a25ba64226e41c6a1d7d5cdbc87a459f/grpcio_tools-1.78.0.tar.gz", hash = "sha256:4b0dd86560274316e155d925158276f8564508193088bc43e20d3f5dff956b2b", size = 5393026, upload-time = "2026-02-06T09:59:59.53Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/70/2118a814a62ab205c905d221064bc09021db83fceeb84764d35c00f0f633/grpcio_tools-1.78.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:ea64e38d1caa2b8468b08cb193f5a091d169b6dbfe1c7dac37d746651ab9d84e", size = 2545568, upload-time = "2026-02-06T09:57:30.308Z" }, - { url = "https://files.pythonhosted.org/packages/2b/a9/68134839dd1a00f964185ead103646d6dd6a396b92ed264eaf521431b793/grpcio_tools-1.78.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:4003fcd5cbb5d578b06176fd45883a72a8f9203152149b7c680ce28653ad9e3a", size = 5708704, upload-time = "2026-02-06T09:57:33.512Z" }, - { url = "https://files.pythonhosted.org/packages/36/1b/b6135aa9534e22051c53e5b9c0853d18024a41c50aaff464b7b47c1ed379/grpcio_tools-1.78.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe6b0081775394c61ec633c9ff5dbc18337100eabb2e946b5c83967fe43b2748", size = 2591905, upload-time = "2026-02-06T09:57:35.338Z" }, - { url = "https://files.pythonhosted.org/packages/41/2b/6380df1390d62b1d18ae18d4d790115abf4997fa29498aa50ba644ecb9d8/grpcio_tools-1.78.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:7e989ad2cd93db52d7f1a643ecaa156ac55bf0484f1007b485979ce8aef62022", size = 2905271, upload-time = "2026-02-06T09:57:37.932Z" }, - { url = "https://files.pythonhosted.org/packages/3a/07/9b369f37c8f4956b68778c044d57390a8f0f3b1cca590018809e75a4fce2/grpcio_tools-1.78.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b874991797e96c41a37e563236c3317ed41b915eff25b292b202d6277d30da85", size = 2656234, upload-time = "2026-02-06T09:57:41.157Z" }, - { url = "https://files.pythonhosted.org/packages/51/61/40eee40e7a54f775a0d4117536532713606b6b177fff5e327f33ad18746e/grpcio_tools-1.78.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:daa8c288b728228377aaf758925692fc6068939d9fa32f92ca13dedcbeb41f33", size = 3105770, upload-time = "2026-02-06T09:57:43.373Z" }, - { url = "https://files.pythonhosted.org/packages/b6/ac/81ee4b728e70e8ba66a589f86469925ead02ed6f8973434e4a52e3576148/grpcio_tools-1.78.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:87e648759b06133199f4bc0c0053e3819f4ec3b900dc399e1097b6065db998b5", size = 3654896, upload-time = "2026-02-06T09:57:45.402Z" }, - { url = "https://files.pythonhosted.org/packages/be/b9/facb3430ee427c800bb1e39588c85685677ea649491d6e0874bd9f3a1c0e/grpcio_tools-1.78.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f3d3ced52bfe39eba3d24f5a8fab4e12d071959384861b41f0c52ca5399d6920", size = 3322529, upload-time = "2026-02-06T09:57:47.292Z" }, - { url = "https://files.pythonhosted.org/packages/c7/de/d7a011df9abfed8c30f0d2077b0562a6e3edc57cb3e5514718e2a81f370a/grpcio_tools-1.78.0-cp310-cp310-win32.whl", hash = "sha256:4bb6ed690d417b821808796221bde079377dff98fdc850ac157ad2f26cda7a36", size = 993518, upload-time = "2026-02-06T09:57:48.836Z" }, - { url = "https://files.pythonhosted.org/packages/c8/5e/f7f60c3ae2281c6b438c3a8455f4a5d5d2e677cf20207864cbee3763da22/grpcio_tools-1.78.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c676d8342fd53bd85a5d5f0d070cd785f93bc040510014708ede6fcb32fada1", size = 1158505, upload-time = "2026-02-06T09:57:50.633Z" }, - { url = "https://files.pythonhosted.org/packages/75/78/280184d19242ed6762bf453c47a70b869b3c5c72a24dc5bf2bf43909faa3/grpcio_tools-1.78.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:6a8b8b7b49f319d29dbcf507f62984fa382d1d10437d75c3f26db5f09c4ac0af", size = 2545904, upload-time = "2026-02-06T09:57:52.769Z" }, - { url = "https://files.pythonhosted.org/packages/5b/51/3c46dea5113f68fe879961cae62d34bb7a3c308a774301b45d614952ee98/grpcio_tools-1.78.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:d62cf3b68372b0c6d722a6165db41b976869811abeabc19c8522182978d8db10", size = 5709078, upload-time = "2026-02-06T09:57:56.389Z" }, - { url = "https://files.pythonhosted.org/packages/e0/2c/dc1ae9ec53182c96d56dfcbf3bcd3e55a8952ad508b188c75bf5fc8993d4/grpcio_tools-1.78.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fa9056742efeaf89d5fe14198af71e5cbc4fbf155d547b89507e19d6025906c6", size = 2591744, upload-time = "2026-02-06T09:57:58.341Z" }, - { url = "https://files.pythonhosted.org/packages/04/63/9b53fc9a9151dd24386785171a4191ee7cb5afb4d983b6a6a87408f41b28/grpcio_tools-1.78.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:e3191af125dcb705aa6bc3856ba81ba99b94121c1b6ebee152e66ea084672831", size = 2905113, upload-time = "2026-02-06T09:58:00.38Z" }, - { url = "https://files.pythonhosted.org/packages/96/b2/0ad8d789f3a2a00893131c140865605fa91671a6e6fcf9da659e1fabba10/grpcio_tools-1.78.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:283239ddbb67ae83fac111c61b25d8527a1dbd355b377cbc8383b79f1329944d", size = 2656436, upload-time = "2026-02-06T09:58:03.038Z" }, - { url = "https://files.pythonhosted.org/packages/09/4d/580f47ce2fc61b093ade747b378595f51b4f59972dd39949f7444b464a03/grpcio_tools-1.78.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ac977508c0db15301ef36d6c79769ec1a6cc4e3bc75735afca7fe7e360cead3a", size = 3106128, upload-time = "2026-02-06T09:58:05.064Z" }, - { url = "https://files.pythonhosted.org/packages/c9/29/d83b2d89f8d10e438bad36b1eb29356510fb97e81e6a608b22ae1890e8e6/grpcio_tools-1.78.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4ff605e25652a0bd13aa8a73a09bc48669c68170902f5d2bf1468a57d5e78771", size = 3654953, upload-time = "2026-02-06T09:58:07.15Z" }, - { url = "https://files.pythonhosted.org/packages/08/71/917ce85633311e54fefd7e6eb1224fb780ef317a4d092766f5630c3fc419/grpcio_tools-1.78.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0197d7b561c79be78ab93d0fe2836c8def470683df594bae3ac89dd8e5c821b2", size = 3322630, upload-time = "2026-02-06T09:58:10.305Z" }, - { url = "https://files.pythonhosted.org/packages/b2/55/3fbf6b26ab46fc79e1e6f7f4e0993cf540263dad639290299fad374a0829/grpcio_tools-1.78.0-cp311-cp311-win32.whl", hash = "sha256:28f71f591f7f39555863ced84fcc209cbf4454e85ef957232f43271ee99af577", size = 993804, upload-time = "2026-02-06T09:58:13.698Z" }, - { url = "https://files.pythonhosted.org/packages/73/86/4affe006d9e1e9e1c6653d6aafe2f8b9188acb2b563cd8ed3a2c7c0e8aec/grpcio_tools-1.78.0-cp311-cp311-win_amd64.whl", hash = "sha256:5a6de495dabf86a3b40b9a7492994e1232b077af9d63080811838b781abbe4e8", size = 1158566, upload-time = "2026-02-06T09:58:15.721Z" }, - { url = "https://files.pythonhosted.org/packages/0c/ae/5b1fa5dd8d560a6925aa52de0de8731d319f121c276e35b9b2af7cc220a2/grpcio_tools-1.78.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:9eb122da57d4cad7d339fc75483116f0113af99e8d2c67f3ef9cae7501d806e4", size = 2546823, upload-time = "2026-02-06T09:58:17.944Z" }, - { url = "https://files.pythonhosted.org/packages/a7/ed/d33ccf7fa701512efea7e7e23333b748848a123e9d3bbafde4e126784546/grpcio_tools-1.78.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d0c501b8249940b886420e6935045c44cb818fa6f265f4c2b97d5cff9cb5e796", size = 5706776, upload-time = "2026-02-06T09:58:20.944Z" }, - { url = "https://files.pythonhosted.org/packages/c6/69/4285583f40b37af28277fc6b867d636e3b10e1b6a7ebd29391a856e1279b/grpcio_tools-1.78.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:77e5aa2d2a7268d55b1b113f958264681ef1994c970f69d48db7d4683d040f57", size = 2593972, upload-time = "2026-02-06T09:58:23.29Z" }, - { url = "https://files.pythonhosted.org/packages/d7/eb/ecc1885bd6b3147f0a1b7dff5565cab72f01c8f8aa458f682a1c77a9fb08/grpcio_tools-1.78.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:8e3c0b0e6ba5275322ba29a97bf890565a55f129f99a21b121145e9e93a22525", size = 2905531, upload-time = "2026-02-06T09:58:25.406Z" }, - { url = "https://files.pythonhosted.org/packages/ae/a9/511d0040ced66960ca10ba0f082d6b2d2ee6dd61837b1709636fdd8e23b4/grpcio_tools-1.78.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:975d4cb48694e20ebd78e1643e5f1cd94cdb6a3d38e677a8e84ae43665aa4790", size = 2656909, upload-time = "2026-02-06T09:58:28.022Z" }, - { url = "https://files.pythonhosted.org/packages/06/a3/3d2c707e7dee8df842c96fbb24feb2747e506e39f4a81b661def7fed107c/grpcio_tools-1.78.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:553ff18c5d52807dedecf25045ae70bad7a3dbba0b27a9a3cdd9bcf0a1b7baec", size = 3109778, upload-time = "2026-02-06T09:58:30.091Z" }, - { url = "https://files.pythonhosted.org/packages/1f/4b/646811ba241bf05da1f0dc6f25764f1c837f78f75b4485a4210c84b79eae/grpcio_tools-1.78.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:8c7f5e4af5a84d2e96c862b1a65e958a538237e268d5f8203a3a784340975b51", size = 3658763, upload-time = "2026-02-06T09:58:32.875Z" }, - { url = "https://files.pythonhosted.org/packages/45/de/0a5ef3b3e79d1011375f5580dfee3a9c1ccb96c5f5d1c74c8cee777a2483/grpcio_tools-1.78.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:96183e2b44afc3f9a761e9d0f985c3b44e03e8bb98e626241a6cbfb3b6f7e88f", size = 3325116, upload-time = "2026-02-06T09:58:34.894Z" }, - { url = "https://files.pythonhosted.org/packages/95/d2/6391b241ad571bc3e71d63f957c0b1860f0c47932d03c7f300028880f9b8/grpcio_tools-1.78.0-cp312-cp312-win32.whl", hash = "sha256:2250e8424c565a88573f7dc10659a0b92802e68c2a1d57e41872c9b88ccea7a6", size = 993493, upload-time = "2026-02-06T09:58:37.242Z" }, - { url = "https://files.pythonhosted.org/packages/7c/8f/7d0d3a39ecad76ccc136be28274daa660569b244fa7d7d0bbb24d68e5ece/grpcio_tools-1.78.0-cp312-cp312-win_amd64.whl", hash = "sha256:217d1fa29de14d9c567d616ead7cb0fef33cde36010edff5a9390b00d52e5094", size = 1158423, upload-time = "2026-02-06T09:58:40.072Z" }, - { url = "https://files.pythonhosted.org/packages/53/ce/17311fb77530420e2f441e916b347515133e83d21cd6cc77be04ce093d5b/grpcio_tools-1.78.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:2d6de1cc23bdc1baafc23e201b1e48c617b8c1418b4d8e34cebf72141676e5fb", size = 2546284, upload-time = "2026-02-06T09:58:43.073Z" }, - { url = "https://files.pythonhosted.org/packages/1d/d3/79e101483115f0e78223397daef71751b75eba7e92a32060c10aae11ca64/grpcio_tools-1.78.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:2afeaad88040894c76656202ff832cb151bceb05c0e6907e539d129188b1e456", size = 5705653, upload-time = "2026-02-06T09:58:45.533Z" }, - { url = "https://files.pythonhosted.org/packages/8b/a7/52fa3ccb39ceeee6adc010056eadfbca8198651c113e418dafebbdf2b306/grpcio_tools-1.78.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:33cc593735c93c03d63efe7a8ba25f3c66f16c52f0651910712490244facad72", size = 2592788, upload-time = "2026-02-06T09:58:48.918Z" }, - { url = "https://files.pythonhosted.org/packages/68/08/682ff6bb548225513d73dc9403742d8975439d7469c673bc534b9bbc83a7/grpcio_tools-1.78.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:2921d7989c4d83b71f03130ab415fa4d66e6693b8b8a1fcbb7a1c67cff19b812", size = 2905157, upload-time = "2026-02-06T09:58:51.478Z" }, - { url = "https://files.pythonhosted.org/packages/b2/66/264f3836a96423b7018e5ada79d62576a6401f6da4e1f4975b18b2be1265/grpcio_tools-1.78.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e6a0df438e82c804c7b95e3f311c97c2f876dcc36376488d5b736b7bcf5a9b45", size = 2656166, upload-time = "2026-02-06T09:58:54.117Z" }, - { url = "https://files.pythonhosted.org/packages/f3/6b/f108276611522e03e98386b668cc7e575eff6952f2db9caa15b2a3b3e883/grpcio_tools-1.78.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e9c6070a9500798225191ef25d0055a15d2c01c9c8f2ee7b681fffa99c98c822", size = 3109110, upload-time = "2026-02-06T09:58:56.891Z" }, - { url = "https://files.pythonhosted.org/packages/6f/c7/cf048dbcd64b3396b3c860a2ffbcc67a8f8c87e736aaa74c2e505a7eee4c/grpcio_tools-1.78.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:394e8b57d85370a62e5b0a4d64c96fcf7568345c345d8590c821814d227ecf1d", size = 3657863, upload-time = "2026-02-06T09:58:59.176Z" }, - { url = "https://files.pythonhosted.org/packages/b6/37/e2736912c8fda57e2e57a66ea5e0bc8eb9a5fb7ded00e866ad22d50afb08/grpcio_tools-1.78.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3ef700293ab375e111a2909d87434ed0a0b086adf0ce67a8d9cf12ea7765e63", size = 3324748, upload-time = "2026-02-06T09:59:01.242Z" }, - { url = "https://files.pythonhosted.org/packages/1c/5d/726abc75bb5bfc2841e88ea05896e42f51ca7c30cb56da5c5b63058b3867/grpcio_tools-1.78.0-cp313-cp313-win32.whl", hash = "sha256:6993b960fec43a8d840ee5dc20247ef206c1a19587ea49fe5e6cc3d2a09c1585", size = 993074, upload-time = "2026-02-06T09:59:03.085Z" }, - { url = "https://files.pythonhosted.org/packages/c5/68/91b400bb360faf9b177ffb5540ec1c4d06ca923691ddf0f79e2c9683f4da/grpcio_tools-1.78.0-cp313-cp313-win_amd64.whl", hash = "sha256:275ce3c2978842a8cf9dd88dce954e836e590cf7029649ad5d1145b779039ed5", size = 1158185, upload-time = "2026-02-06T09:59:05.036Z" }, - { url = "https://files.pythonhosted.org/packages/cf/5e/278f3831c8d56bae02e3acc570465648eccf0a6bbedcb1733789ac966803/grpcio_tools-1.78.0-cp314-cp314-linux_armv7l.whl", hash = "sha256:8b080d0d072e6032708a3a91731b808074d7ab02ca8fb9847b6a011fdce64cd9", size = 2546270, upload-time = "2026-02-06T09:59:07.426Z" }, - { url = "https://files.pythonhosted.org/packages/a3/d9/68582f2952b914b60dddc18a2e3f9c6f09af9372b6f6120d6cf3ec7f8b4e/grpcio_tools-1.78.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:8c0ad8f8f133145cd7008b49cb611a5c6a9d89ab276c28afa17050516e801f79", size = 5705731, upload-time = "2026-02-06T09:59:09.856Z" }, - { url = "https://files.pythonhosted.org/packages/70/68/feb0f9a48818ee1df1e8b644069379a1e6ef5447b9b347c24e96fd258e5d/grpcio_tools-1.78.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2f8ea092a7de74c6359335d36f0674d939a3c7e1a550f4c2c9e80e0226de8fe4", size = 2593896, upload-time = "2026-02-06T09:59:12.23Z" }, - { url = "https://files.pythonhosted.org/packages/1f/08/a430d8d06e1b8d33f3e48d3f0cc28236723af2f35e37bd5c8db05df6c3aa/grpcio_tools-1.78.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:da422985e0cac822b41822f43429c19ecb27c81ffe3126d0b74e77edec452608", size = 2905298, upload-time = "2026-02-06T09:59:14.458Z" }, - { url = "https://files.pythonhosted.org/packages/71/0a/348c36a3eae101ca0c090c9c3bc96f2179adf59ee0c9262d11cdc7bfe7db/grpcio_tools-1.78.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4fab1faa3fbcb246263e68da7a8177d73772283f9db063fb8008517480888d26", size = 2656186, upload-time = "2026-02-06T09:59:16.949Z" }, - { url = "https://files.pythonhosted.org/packages/1d/3f/18219f331536fad4af6207ade04142292faa77b5cb4f4463787988963df8/grpcio_tools-1.78.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:dd9c094f73f734becae3f20f27d4944d3cd8fb68db7338ee6c58e62fc5c3d99f", size = 3109859, upload-time = "2026-02-06T09:59:19.202Z" }, - { url = "https://files.pythonhosted.org/packages/5b/d9/341ea20a44c8e5a3a18acc820b65014c2e3ea5b4f32a53d14864bcd236bc/grpcio_tools-1.78.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:2ed51ce6b833068f6c580b73193fc2ec16468e6bc18354bc2f83a58721195a58", size = 3657915, upload-time = "2026-02-06T09:59:21.839Z" }, - { url = "https://files.pythonhosted.org/packages/fb/f4/5978b0f91611a64371424c109dd0027b247e5b39260abad2eaee66b6aa37/grpcio_tools-1.78.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:05803a5cdafe77c8bdf36aa660ad7a6a1d9e49bc59ce45c1bade2a4698826599", size = 3324724, upload-time = "2026-02-06T09:59:24.402Z" }, - { url = "https://files.pythonhosted.org/packages/b2/80/96a324dba99cfbd20e291baf0b0ae719dbb62b76178c5ce6c788e7331cb1/grpcio_tools-1.78.0-cp314-cp314-win32.whl", hash = "sha256:f7c722e9ce6f11149ac5bddd5056e70aaccfd8168e74e9d34d8b8b588c3f5c7c", size = 1015505, upload-time = "2026-02-06T09:59:26.3Z" }, - { url = "https://files.pythonhosted.org/packages/3b/d1/909e6a05bfd44d46327dc4b8a78beb2bae4fb245ffab2772e350081aaf7e/grpcio_tools-1.78.0-cp314-cp314-win_amd64.whl", hash = "sha256:7d58ade518b546120ec8f0a8e006fc8076ae5df151250ebd7e82e9b5e152c229", size = 1190196, upload-time = "2026-02-06T09:59:28.359Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/1a/9f/78f4f4946187e242e34aec3e9881eed9c70b4eeaca26551f1989ba9ab66c/grpcio_tools-1.75.0.tar.gz", hash = "sha256:eb5e4025034d92da3c81fd5e3468c33d5ae7571b07a72c385b5ec1746658573f", size = 5390883, upload-time = "2025-09-16T09:22:48.83Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/0c/000eead009abfb7d9995f6bc66e94f0feb438a89546ad40b7640491b247a/grpcio_tools-1.75.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:5ca29b0ae735044c6a48072cf7bf53e34ce9ab03eec66acaf2173071d4f66d8a", size = 2545418, upload-time = "2025-09-16T09:20:46.943Z" }, + { url = "https://files.pythonhosted.org/packages/03/a5/39ec53aa9707022ad9cd90d8e3539754fc6eee12716c02ef03083602f75a/grpcio_tools-1.75.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:d1a224887f70981683dfcaacc253c08f3680b919c0b2353fbb57f89b27e1c9b9", size = 5841655, upload-time = "2025-09-16T09:20:53.161Z" }, + { url = "https://files.pythonhosted.org/packages/b9/90/0b48f2cb003483202b7198b2ae190e41d06a820aca04cf7ad3acd7a2e77a/grpcio_tools-1.75.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c49649d2b46a5a09419631adec105b05bcb016e5727c8f1b08ac8e16d9b0e3e0", size = 2591559, upload-time = "2025-09-16T09:20:55.573Z" }, + { url = "https://files.pythonhosted.org/packages/57/30/2bec888159b4dfc01ddf06381306f37f7881349f3b6fe5bd6e482c8bf487/grpcio_tools-1.75.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:c944610bc009185f3da399030a2a8a9d550ae3246f93ad20ff63593fa883ddfb", size = 2904893, upload-time = "2025-09-16T09:20:57.857Z" }, + { url = "https://files.pythonhosted.org/packages/f9/52/28f01e25dfc6fff6776e0e7cff11919137b2b9931b948bb44a9a37e780a9/grpcio_tools-1.75.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:186c11fe9c8ef90b0862013b61876693644c952fda8fffef6ab0de0a83f90479", size = 2656148, upload-time = "2025-09-16T09:20:59.67Z" }, + { url = "https://files.pythonhosted.org/packages/ff/8b/c4036689b7ada7e8ce94f06c492190c293378375b54d84b9b93b9497e9e5/grpcio_tools-1.75.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:688668666265a8f3e5eb86f73694e8adac2d2cc5f40c90249ce80bf6c6cec9ea", size = 3105152, upload-time = "2025-09-16T09:21:01.639Z" }, + { url = "https://files.pythonhosted.org/packages/40/76/4867d716c312601ae1e95c0f3f24fec2250ac13a6e135a28fe3e52e2c25e/grpcio_tools-1.75.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9083fe53cbe17b972d9ede47b1e6c82ec532a91770d41c790c4f9b39291041c3", size = 3654549, upload-time = "2025-09-16T09:21:03.667Z" }, + { url = "https://files.pythonhosted.org/packages/57/75/9781d4cf3e198b0146e5df26a497f7e07fe0e2ba10cf366d35796000a411/grpcio_tools-1.75.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3072b10f4ad82739650aa9d667b536de8d4973083236215b7bf2389ba75bb507", size = 3322218, upload-time = "2025-09-16T09:21:06.099Z" }, + { url = "https://files.pythonhosted.org/packages/15/64/f7d643b8b1c0f85d6558cf4cc62d8222bbdad7dffaf5f984ee016e85acdb/grpcio_tools-1.75.0-cp310-cp310-win32.whl", hash = "sha256:c42fc86ab55018ba5afe2aa95d6d34e2e763da06eff23c08bed487a556341071", size = 992983, upload-time = "2025-09-16T09:21:07.971Z" }, + { url = "https://files.pythonhosted.org/packages/b3/53/6afd4982379f7027372d77939f8e7cb3805756b8ea1a3f48af89e6a98ebd/grpcio_tools-1.75.0-cp310-cp310-win_amd64.whl", hash = "sha256:5e0c8d5d4bdce7f32e2fef3e2304cdca1fbb16a6469c7d3bce38884ee4c449d1", size = 1157424, upload-time = "2025-09-16T09:21:09.984Z" }, + { url = "https://files.pythonhosted.org/packages/60/b9/e5644dd1999c13e7057d46a77204f287bc589ffe222783afa1782927fca9/grpcio_tools-1.75.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:6c3b8dbe8b2ad7df4ba661b5ee29ae8fe79d2715aade519847deaef26f5c1a06", size = 2545461, upload-time = "2025-09-16T09:21:12.869Z" }, + { url = "https://files.pythonhosted.org/packages/cb/72/144792c81544d2e85b1b80fd17ec85cb13f94f409af36a18a32f8f5f4785/grpcio_tools-1.75.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:cdbccc5a4809ef9414b7c434dd1aabc94b66a01c01c13ecc1edba9f8f4277b44", size = 5843012, upload-time = "2025-09-16T09:21:15.357Z" }, + { url = "https://files.pythonhosted.org/packages/9b/6c/78e7e09b103e98953eaa2c546572c94107c175fd8a13aa208122ecd6b674/grpcio_tools-1.75.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:16a9597d1bd4143a71bfae341a32952a64c094a63d3d0bdd24b21fdc8b843846", size = 2591669, upload-time = "2025-09-16T09:21:18.32Z" }, + { url = "https://files.pythonhosted.org/packages/cd/7d/8ba7b2ccb3a144d570a3aa6f6b65a455050430640ff4bcfe3cb7dd57fafa/grpcio_tools-1.75.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:899c46520446ad1935f5899729746b390e13085e9757d043401298b18fa37d99", size = 2904952, upload-time = "2025-09-16T09:21:20.413Z" }, + { url = "https://files.pythonhosted.org/packages/6c/b3/be83fea7df617421e9cd0ffabb5cc0ff7737c2699d4004507490c29999b1/grpcio_tools-1.75.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:53c116d0d5df70845330eefb98ef4242ff09be264a22bc5e18f171a3047c9e66", size = 2656311, upload-time = "2025-09-16T09:21:22.219Z" }, + { url = "https://files.pythonhosted.org/packages/b4/de/d573719605e1f891815019410ed63d03832e401cd6bd48073ae9ad74a242/grpcio_tools-1.75.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:495ce168f996d4c42328e17b788d51d808fc585a80612fe70943c00ac16d0fca", size = 3105582, upload-time = "2025-09-16T09:21:24.401Z" }, + { url = "https://files.pythonhosted.org/packages/fd/ed/e82486e142de0d56f7b14687d0bbd9162da98f169dd681e3038a6d0b53e4/grpcio_tools-1.75.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:26f1f3cedebe465f97b5aad312fb775a4bd53a0e88d08c4000e588c195519eca", size = 3654677, upload-time = "2025-09-16T09:21:26.468Z" }, + { url = "https://files.pythonhosted.org/packages/7e/65/fc2c321f26fd7714b5ec05be3fdd27a0f825bcfe11e5f071b3ebfcbf3d83/grpcio_tools-1.75.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:82692be482cdcf7ac9b79563dbea99333835aaa3f5e7f0641689766b64b91543", size = 3322146, upload-time = "2025-09-16T09:21:29.66Z" }, + { url = "https://files.pythonhosted.org/packages/87/4b/8bdd4edb696fd979d71ad087052c3ffe73ffaf6539aad743298723bd3191/grpcio_tools-1.75.0-cp311-cp311-win32.whl", hash = "sha256:fd038847974aeb883ee0f3b5b535d85618ad32789c15c9bf24af6c12a44f67f1", size = 993386, upload-time = "2025-09-16T09:21:31.362Z" }, + { url = "https://files.pythonhosted.org/packages/84/80/6939b0fc8a5fe493058293af758de798963a8e9879f16aa0813116859c63/grpcio_tools-1.75.0-cp311-cp311-win_amd64.whl", hash = "sha256:5c5465cd7b83c34f3c987a235fe3b04012411502d4bc66de5a34b238617ded4c", size = 1157908, upload-time = "2025-09-16T09:21:33.143Z" }, + { url = "https://files.pythonhosted.org/packages/13/50/d654ee2d2e763f41c53e5e0282c0f422d2e129414a7f156c61660132c780/grpcio_tools-1.75.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:6ded12c79fb56ceae0ce60e653453159bfc2ccb044922b7e7d721de6c8e04506", size = 2546098, upload-time = "2025-09-16T09:21:35.497Z" }, + { url = "https://files.pythonhosted.org/packages/e3/5b/30fc9980e5571de7f5e442e6598f6c3d1d7860f15b8fa0058678da6903fb/grpcio_tools-1.75.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:ebdac7cc820459874f3b19eddddae19c0c7e7cdf228aee8e7567cec1fddb2ae3", size = 5839860, upload-time = "2025-09-16T09:21:37.799Z" }, + { url = "https://files.pythonhosted.org/packages/72/ec/64568f58f3538142e6bfd21c2b1a6be67b33a7d41ff7c6a659c9ec54da11/grpcio_tools-1.75.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:509ec0ce7c4269c2bea6015efcdcde00a5d55d97c88ad17587b4247cdc3d2fe8", size = 2592915, upload-time = "2025-09-16T09:21:41.981Z" }, + { url = "https://files.pythonhosted.org/packages/c9/d1/442eeec951381ce45db6e4720e14369fea4780fc8fec0b59daa280ed7660/grpcio_tools-1.75.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:a68a8dcbcbd1df33e7c08c2ceeb69ed8fd53e235784ac680dfe3fc1e89aac2ac", size = 2905275, upload-time = "2025-09-16T09:21:44.103Z" }, + { url = "https://files.pythonhosted.org/packages/d9/4a/054d98a5a20f52d06c9183a6220e1439204f20ed10077f27943bbf08a3fa/grpcio_tools-1.75.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3ac8a663e955bf3188f76d93d7fdc656f346ff54ea7e512eb034374c6fd61b50", size = 2656424, upload-time = "2025-09-16T09:21:46.106Z" }, + { url = "https://files.pythonhosted.org/packages/c5/af/f655d74e5722be3f90697da625c5457a75eb13b69f251bc2131e1b0c11c6/grpcio_tools-1.75.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3c30cb36ae1a4ed5fb1960f4bc0000548fecb9ff21a51d78a1f54e3424f971c0", size = 3108985, upload-time = "2025-09-16T09:21:48.852Z" }, + { url = "https://files.pythonhosted.org/packages/96/6f/844d5d8cd81f01e768d9f3eab767ce255ad9c7a5a634900fb8502dd04932/grpcio_tools-1.75.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:35d4368794506db2b0acde60e7e2bae21255cc0d05db9ffc078510ab6a84ff4f", size = 3657939, upload-time = "2025-09-16T09:21:53.349Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d3/974d12ff6751b6706faa94665e997b45bf3ac3084011ea5a5b51cd6be032/grpcio_tools-1.75.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:edefbb90bb7ddc4eadac3463d5f7084e1d43b1d713254f668dd55c25db5b5ef2", size = 3324876, upload-time = "2025-09-16T09:21:55.866Z" }, + { url = "https://files.pythonhosted.org/packages/eb/57/e3d3599dfe11cdad6a653d6f6cff8d951a3fbf529d2cf55b9c1901e51763/grpcio_tools-1.75.0-cp312-cp312-win32.whl", hash = "sha256:c2bad23bd0d43acd9d7032b6ffb04f5eb176d853cd32967eb2c4a39044c81cfe", size = 993071, upload-time = "2025-09-16T09:21:57.677Z" }, + { url = "https://files.pythonhosted.org/packages/cf/53/3414319a5257ec5544515cb8f2416c0d375885613aaba176fa3f1b9a2f34/grpcio_tools-1.75.0-cp312-cp312-win_amd64.whl", hash = "sha256:0f4f31035a5178acd924a052b8954d5ac71319092b57e3711438ca6518b71017", size = 1157504, upload-time = "2025-09-16T09:22:00.104Z" }, + { url = "https://files.pythonhosted.org/packages/23/83/12d9fdaa4b11eabc934c0ecb56eb34a4ca4d2c579540d8b60b67da02d0c2/grpcio_tools-1.75.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:69742254df93323275b7ee5ac017e3b9fdba8ecc6dca00bd6b2cd1c70c80a9c2", size = 2545752, upload-time = "2025-09-16T09:22:02.346Z" }, + { url = "https://files.pythonhosted.org/packages/67/72/8c9cf443eb20822e2de65c66175615e8eb2a0e9091538e232dd3365a301f/grpcio_tools-1.75.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:a07aa71ad96103b18bb84dc069dd139897356116d2aaa68d3df84d4d59701ae8", size = 5838166, upload-time = "2025-09-16T09:22:04.693Z" }, + { url = "https://files.pythonhosted.org/packages/7f/08/484eb789d42c4b828e8c10d11739d87c4484813570f62efc6c2f84829ab3/grpcio_tools-1.75.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:dcfb12654fb1d6ce84f4a55d3dfbc267a04d53dc9b52ee0974b2110d02f68dac", size = 2592147, upload-time = "2025-09-16T09:22:06.722Z" }, + { url = "https://files.pythonhosted.org/packages/6b/b7/43330bfb23b24df3cd90d884dd1cdbd39d9475f481c3386c8cb1a8d67a13/grpcio_tools-1.75.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:990d183fee5a2ef9d4f3a220b6506f5da740271da175efcb7e4e34ebc3191a12", size = 2905215, upload-time = "2025-09-16T09:22:08.713Z" }, + { url = "https://files.pythonhosted.org/packages/0a/b4/96e75212054a32d7bc5a0bf46c9f3257be4033f1fae3a1410ea97e41e544/grpcio_tools-1.75.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:39c6ff052960a3301cd920549384a2ad7cb3165c778feed601cae2a2131b63f8", size = 2656250, upload-time = "2025-09-16T09:22:11.079Z" }, + { url = "https://files.pythonhosted.org/packages/74/e0/6e0ca3e7f1b30ff6861d6268da80a4c4f0531d26116a1e8806edca16e0e5/grpcio_tools-1.75.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:60bd449814fe3cebeda11c0cda3a3adffd81941559aa254e6d153751baa0cffc", size = 3108910, upload-time = "2025-09-16T09:22:13.21Z" }, + { url = "https://files.pythonhosted.org/packages/63/1c/e310b4d3386356a5d36f297a209f88c6bacd0ecca4e779887cc814fcbb48/grpcio_tools-1.75.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:91e430e9368afc38e94645f744840ab06995cfb7312233623c5d7370f8c0dd7c", size = 3657019, upload-time = "2025-09-16T09:22:15.977Z" }, + { url = "https://files.pythonhosted.org/packages/c9/38/215dc6a9ba98b7f74e959bb52ecc66949e336267f499b94ce754e18d0737/grpcio_tools-1.75.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3351acef4b8897e99bdceae5cfcc300e1e5c1d88c0fc2ffc2b5ca1bd5ce4ced8", size = 3324447, upload-time = "2025-09-16T09:22:18.046Z" }, + { url = "https://files.pythonhosted.org/packages/91/75/c7acdef7d023f47ffca893cd3bcf698e71dec9d6946f90efe5575961ec9a/grpcio_tools-1.75.0-cp313-cp313-win32.whl", hash = "sha256:1241f8c65f2429f00d9e15e819aca2138c5aa571f0ac644ab658a0281dc177d9", size = 992434, upload-time = "2025-09-16T09:22:19.92Z" }, + { url = "https://files.pythonhosted.org/packages/a9/9e/221073f576ba94855ceb99949edfe91b22117df898fdb3709cc8f46b7e19/grpcio_tools-1.75.0-cp313-cp313-win_amd64.whl", hash = "sha256:193ce6aef33417849289cbb518402fe60c00d0fa66d68ea9a30c98cb8818280c", size = 1157066, upload-time = "2025-09-16T09:22:21.915Z" }, ] [[package]] From f2503974650b2cd31e8ec93cdfd64a43189e6e0a Mon Sep 17 00:00:00 2001 From: Vaibhav Tiwari Date: Fri, 27 Mar 2026 19:21:29 -0400 Subject: [PATCH 05/14] chore: remove the unused total_partitions from PartitionsResponse class in sourcer/_dtypes Signed-off-by: Vaibhav Tiwari --- packages/pynumaflow/pynumaflow/sourcer/_dtypes.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py b/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py index 65c0843a..b6d7476f 100644 --- a/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py +++ b/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py @@ -245,28 +245,20 @@ class PartitionsResponse: Args: partitions: the list of active partitions. - total_partitions: the total number of partitions in the source (optional). """ _partitions: list[int] - _total_partitions: int | None def __init__(self, partitions: list[int], total_partitions: int | None = None): if not isinstance(partitions, list): raise TypeError(f"Wrong data type: {type(partitions)} for Partition.partitions") self._partitions = partitions - self._total_partitions = total_partitions @property def partitions(self) -> list[int]: """Returns the list of active partitions""" return self._partitions - @property - def total_partitions(self) -> int | None: - """Returns the total number of partitions, or None if not available""" - return self._total_partitions - class Sourcer(metaclass=ABCMeta): """ From 29032030aa4ecaa1e27361d2c0cb92d9e762e2e4 Mon Sep 17 00:00:00 2001 From: Vaibhav Tiwari Date: Fri, 27 Mar 2026 19:22:26 -0400 Subject: [PATCH 06/14] chore: fix __init__ method for PartitionsResponse Signed-off-by: Vaibhav Tiwari --- packages/pynumaflow/pynumaflow/sourcer/_dtypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py b/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py index b6d7476f..122d08d1 100644 --- a/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py +++ b/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py @@ -249,7 +249,7 @@ class PartitionsResponse: _partitions: list[int] - def __init__(self, partitions: list[int], total_partitions: int | None = None): + def __init__(self, partitions: list[int]): if not isinstance(partitions, list): raise TypeError(f"Wrong data type: {type(partitions)} for Partition.partitions") self._partitions = partitions From 036bfe470530a38fcb40c8c7b459d75eb6396d65 Mon Sep 17 00:00:00 2001 From: Vaibhav Tiwari Date: Fri, 27 Mar 2026 19:47:58 -0400 Subject: [PATCH 07/14] break backward compatibility to force implementing active_partitions Signed-off-by: Vaibhav Tiwari --- .../pynumaflow/pynumaflow/sourcer/_dtypes.py | 19 +++---------------- .../pynumaflow/sourcer/async_server.py | 2 +- .../source/test_async_source_shutdown.py | 4 ++-- packages/pynumaflow/tests/source/utils.py | 6 +++--- 4 files changed, 9 insertions(+), 22 deletions(-) diff --git a/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py b/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py index 122d08d1..020b6476 100644 --- a/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py +++ b/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py @@ -297,31 +297,18 @@ async def pending_handler(self) -> PendingResponse: """ pass - async def partitions_handler(self) -> PartitionsResponse: - """ - .. deprecated:: - Use :meth:`active_partitions_handler` instead. - - Returns the active partitions associated with the source. - """ - warnings.warn( - "partitions_handler is deprecated, use active_partitions_handler instead.", - DeprecationWarning, - stacklevel=2, - ) - return PartitionsResponse(partitions=get_default_partitions()) - + @abstractmethod async def active_partitions_handler(self) -> PartitionsResponse: """ Returns the active partitions associated with the source, used by the platform to determine the partitions to which the watermark should be published. Falls back to partitions_handler() if not overridden. """ - return await self.partitions_handler() + pass async def total_partitions_handler(self) -> int | None: """ - Returns the total number of partitions in the source. + Optional. Returns the total number of partitions in the source. Used by the platform for watermark progression to know when all processors have reported in. Returns None by default, indicating the source does not report total partitions. diff --git a/packages/pynumaflow/pynumaflow/sourcer/async_server.py b/packages/pynumaflow/pynumaflow/sourcer/async_server.py index 9c9e6072..93f2f18c 100644 --- a/packages/pynumaflow/pynumaflow/sourcer/async_server.py +++ b/packages/pynumaflow/pynumaflow/sourcer/async_server.py @@ -133,7 +133,7 @@ async def pending_handler(self) -> PendingResponse: ''' return PendingResponse(count=0) - async def partitions_handler(self) -> PartitionsResponse: + async def active_partitions_handler(self) -> PartitionsResponse: ''' The simple source always returns default partitions. ''' diff --git a/packages/pynumaflow/tests/source/test_async_source_shutdown.py b/packages/pynumaflow/tests/source/test_async_source_shutdown.py index b6e537a5..cf640989 100644 --- a/packages/pynumaflow/tests/source/test_async_source_shutdown.py +++ b/packages/pynumaflow/tests/source/test_async_source_shutdown.py @@ -41,7 +41,7 @@ async def nack_handler(self, nack_request: NackRequest): async def pending_handler(self) -> PendingResponse: return PendingResponse(count=0) - async def partitions_handler(self) -> PartitionsResponse: + async def active_partitions_handler(self) -> PartitionsResponse: return PartitionsResponse(partitions=[]) @@ -194,7 +194,7 @@ async def _run(): async def _cancelled_partitions(): raise asyncio.CancelledError() - handler.partitions_handler = _cancelled_partitions + handler.active_partitions_handler = _cancelled_partitions servicer = AsyncSourceServicer(source_handler=handler) shutdown_event = asyncio.Event() diff --git a/packages/pynumaflow/tests/source/utils.py b/packages/pynumaflow/tests/source/utils.py index ece90815..ddd9930a 100644 --- a/packages/pynumaflow/tests/source/utils.py +++ b/packages/pynumaflow/tests/source/utils.py @@ -52,7 +52,7 @@ async def nack_handler(self, nack_request: NackRequest): async def pending_handler(self) -> PendingResponse: return PendingResponse(count=10) - async def partitions_handler(self) -> PartitionsResponse: + async def active_partitions_handler(self) -> PartitionsResponse: return PartitionsResponse(partitions=mock_partitions()) @@ -160,7 +160,7 @@ async def nack_handler(self, nack_request: NackRequest): async def pending_handler(self) -> PendingResponse: raise RuntimeError("Got a runtime error from pending handler.") - async def partitions_handler(self) -> PartitionsResponse: + async def active_partitions_handler(self) -> PartitionsResponse: raise RuntimeError("Got a runtime error from partition handler.") @@ -177,5 +177,5 @@ def nack_handler(self, nack_request: NackRequest): def pending_handler(self) -> PendingResponse: raise RuntimeError("Got a runtime error from pending handler.") - def partitions_handler(self) -> PartitionsResponse: + def active_partitions_handler(self) -> PartitionsResponse: raise RuntimeError("Got a runtime error from partition handler.") From d3aae0bee3f883be0b27bfd117e3743ea5a741c7 Mon Sep 17 00:00:00 2001 From: Vaibhav Tiwari Date: Fri, 27 Mar 2026 20:05:40 -0400 Subject: [PATCH 08/14] chore: fix linting Signed-off-by: Vaibhav Tiwari --- packages/pynumaflow/pynumaflow/sourcer/_dtypes.py | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py b/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py index 020b6476..ab96655d 100644 --- a/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py +++ b/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py @@ -1,5 +1,4 @@ import os -import warnings from abc import ABCMeta, abstractmethod from collections.abc import AsyncIterator, Callable, Iterator from dataclasses import dataclass From 6948b2e4c472499521ceded6b726d2ac87bdb5c2 Mon Sep 17 00:00:00 2001 From: Vaibhav Kant Tiwari Date: Fri, 27 Mar 2026 11:57:03 -0400 Subject: [PATCH 09/14] chore: [pynumaflow-lite] lint and clippy checks in makefile (#344) Signed-off-by: Vaibhav Tiwari --- packages/pynumaflow-lite/Makefile | 14 ++++++++ .../pynumaflow-lite/src/accumulate/server.rs | 2 +- .../pynumaflow-lite/src/batchmap/server.rs | 2 +- packages/pynumaflow-lite/src/lib.rs | 22 ++++++------- packages/pynumaflow-lite/src/map/server.rs | 2 +- .../pynumaflow-lite/src/mapstream/server.rs | 2 +- packages/pynumaflow-lite/src/pyiterables.rs | 4 ++- packages/pynumaflow-lite/src/reduce/server.rs | 32 ++++++++----------- .../src/reducestream/server.rs | 2 +- .../src/session_reduce/server.rs | 2 +- .../pynumaflow-lite/src/sideinput/server.rs | 5 +-- packages/pynumaflow-lite/src/sink/mod.rs | 1 + packages/pynumaflow-lite/src/sink/server.rs | 5 +-- packages/pynumaflow-lite/src/source/server.rs | 6 ++-- .../src/sourcetransform/server.rs | 2 +- .../pynumaflow-lite/tests/bin/batchmap.rs | 2 +- .../pynumaflow-lite/tests/bin/mapstream.rs | 2 +- .../pynumaflow-lite/tests/bin/reducestream.rs | 30 ++++++++--------- packages/pynumaflow-lite/tests/bin/source.rs | 8 ++--- 19 files changed, 73 insertions(+), 72 deletions(-) diff --git a/packages/pynumaflow-lite/Makefile b/packages/pynumaflow-lite/Makefile index ae7d02a0..8f0f8c58 100644 --- a/packages/pynumaflow-lite/Makefile +++ b/packages/pynumaflow-lite/Makefile @@ -42,3 +42,17 @@ test-rust: clean: cargo clean + +fmt: + cargo fmt --all + +.PHONY: lint +lint: test-fmt clippy + +.PHONY: test-fmt +test-fmt: + cargo fmt --all --check + +.PHONY: clippy +clippy: + cargo clippy --workspace --all-targets --all-features -- -D warnings -A clippy::module_inception \ No newline at end of file diff --git a/packages/pynumaflow-lite/src/accumulate/server.rs b/packages/pynumaflow-lite/src/accumulate/server.rs index 7a39054c..ecd8e13d 100644 --- a/packages/pynumaflow-lite/src/accumulate/server.rs +++ b/packages/pynumaflow-lite/src/accumulate/server.rs @@ -155,7 +155,7 @@ pub(super) async fn start( // if not finished, abort it if !sig_handle.is_finished() { println!("Aborting signal handler"); - let _ = sig_handle.abort(); + sig_handle.abort(); } result diff --git a/packages/pynumaflow-lite/src/batchmap/server.rs b/packages/pynumaflow-lite/src/batchmap/server.rs index 65a5d879..25c75210 100644 --- a/packages/pynumaflow-lite/src/batchmap/server.rs +++ b/packages/pynumaflow-lite/src/batchmap/server.rs @@ -99,7 +99,7 @@ pub(super) async fn start( // if not finished, abort it if !sig_handle.is_finished() { println!("Aborting signal handler"); - let _ = sig_handle.abort(); + sig_handle.abort(); } result diff --git a/packages/pynumaflow-lite/src/lib.rs b/packages/pynumaflow-lite/src/lib.rs index 0f5a7c2d..1e25b912 100644 --- a/packages/pynumaflow-lite/src/lib.rs +++ b/packages/pynumaflow-lite/src/lib.rs @@ -114,7 +114,7 @@ fn pynumaflow_lite(py: Python, m: &Bound) -> PyResult<()> { sub.setattr("__name__", fullname)?; py.import("sys")? .getattr("modules")? - .set_item(fullname, &sub)?; + .set_item(fullname, sub)?; // Ensure it's importable as `pynumaflow_lite.batchmapper` as well let binding = m.getattr("batchmapper")?; @@ -123,7 +123,7 @@ fn pynumaflow_lite(py: Python, m: &Bound) -> PyResult<()> { sub.setattr("__name__", fullname)?; py.import("sys")? .getattr("modules")? - .set_item(fullname, &sub)?; + .set_item(fullname, sub)?; // Ensure it's importable as `pynumaflow_lite.mapstreamer` as well let binding = m.getattr("mapstreamer")?; @@ -132,7 +132,7 @@ fn pynumaflow_lite(py: Python, m: &Bound) -> PyResult<()> { sub.setattr("__name__", fullname)?; py.import("sys")? .getattr("modules")? - .set_item(fullname, &sub)?; + .set_item(fullname, sub)?; // Ensure it's importable as `pynumaflow_lite.reducer` as well let binding = m.getattr("reducer")?; @@ -141,7 +141,7 @@ fn pynumaflow_lite(py: Python, m: &Bound) -> PyResult<()> { sub.setattr("__name__", fullname)?; py.import("sys")? .getattr("modules")? - .set_item(fullname, &sub)?; + .set_item(fullname, sub)?; // Ensure it's importable as `pynumaflow_lite.session_reducer` as well let binding = m.getattr("session_reducer")?; @@ -150,7 +150,7 @@ fn pynumaflow_lite(py: Python, m: &Bound) -> PyResult<()> { sub.setattr("__name__", fullname)?; py.import("sys")? .getattr("modules")? - .set_item(fullname, &sub)?; + .set_item(fullname, sub)?; // Ensure it's importable as `pynumaflow_lite.reducestreamer` as well let binding = m.getattr("reducestreamer")?; @@ -159,7 +159,7 @@ fn pynumaflow_lite(py: Python, m: &Bound) -> PyResult<()> { sub.setattr("__name__", fullname)?; py.import("sys")? .getattr("modules")? - .set_item(fullname, &sub)?; + .set_item(fullname, sub)?; // Ensure it's importable as `pynumaflow_lite.accumulator` as well let binding = m.getattr("accumulator")?; @@ -168,7 +168,7 @@ fn pynumaflow_lite(py: Python, m: &Bound) -> PyResult<()> { sub.setattr("__name__", fullname)?; py.import("sys")? .getattr("modules")? - .set_item(fullname, &sub)?; + .set_item(fullname, sub)?; // Ensure it's importable as `pynumaflow_lite.sinker` as well let binding = m.getattr("sinker")?; @@ -177,7 +177,7 @@ fn pynumaflow_lite(py: Python, m: &Bound) -> PyResult<()> { sub.setattr("__name__", fullname)?; py.import("sys")? .getattr("modules")? - .set_item(fullname, &sub)?; + .set_item(fullname, sub)?; // Ensure it's importable as `pynumaflow_lite.sourcer` as well let binding = m.getattr("sourcer")?; @@ -186,7 +186,7 @@ fn pynumaflow_lite(py: Python, m: &Bound) -> PyResult<()> { sub.setattr("__name__", fullname)?; py.import("sys")? .getattr("modules")? - .set_item(fullname, &sub)?; + .set_item(fullname, sub)?; // Ensure it's importable as `pynumaflow_lite.sourcetransformer` as well let binding = m.getattr("sourcetransformer")?; @@ -195,7 +195,7 @@ fn pynumaflow_lite(py: Python, m: &Bound) -> PyResult<()> { sub.setattr("__name__", fullname)?; py.import("sys")? .getattr("modules")? - .set_item(fullname, &sub)?; + .set_item(fullname, sub)?; // Ensure it's importable as `pynumaflow_lite.sideinputer` as well let binding = m.getattr("sideinputer")?; @@ -204,7 +204,7 @@ fn pynumaflow_lite(py: Python, m: &Bound) -> PyResult<()> { sub.setattr("__name__", fullname)?; py.import("sys")? .getattr("modules")? - .set_item(fullname, &sub)?; + .set_item(fullname, sub)?; Ok(()) } diff --git a/packages/pynumaflow-lite/src/map/server.rs b/packages/pynumaflow-lite/src/map/server.rs index 8817e6ff..1e220994 100644 --- a/packages/pynumaflow-lite/src/map/server.rs +++ b/packages/pynumaflow-lite/src/map/server.rs @@ -80,7 +80,7 @@ pub(super) async fn start( // if not finished, abort it if !sig_handle.is_finished() { println!("Aborting signal handler"); - let _ = sig_handle.abort(); + sig_handle.abort(); } result diff --git a/packages/pynumaflow-lite/src/mapstream/server.rs b/packages/pynumaflow-lite/src/mapstream/server.rs index a90eda27..7dbcaee1 100644 --- a/packages/pynumaflow-lite/src/mapstream/server.rs +++ b/packages/pynumaflow-lite/src/mapstream/server.rs @@ -95,7 +95,7 @@ pub(super) async fn start( // if not finished, abort it if !sig_handle.is_finished() { println!("Aborting signal handler"); - let _ = sig_handle.abort(); + sig_handle.abort(); } result diff --git a/packages/pynumaflow-lite/src/pyiterables.rs b/packages/pynumaflow-lite/src/pyiterables.rs index fc4e33c5..d85721d0 100644 --- a/packages/pynumaflow-lite/src/pyiterables.rs +++ b/packages/pynumaflow-lite/src/pyiterables.rs @@ -11,6 +11,8 @@ use pyo3::{PyClass, exceptions::PyStopAsyncIteration, prelude::*}; use tokio::sync::Mutex as AsyncMutex; use tokio::sync::mpsc; +type PyFuture = Pin>> + Send + 'static>>; + /// Stream over a Python AsyncIterator, yielding `M` as soon as each value is produced. /// `M` must be extractable from the Python object. /// @@ -24,7 +26,7 @@ pub struct PyAsyncIterStream { event_loop: Arc>, // In-flight future for the next item (converted from Python awaitable). #[pin] - next_fut: Option>> + Send + 'static>>>, + next_fut: Option, // Phantom: we yield M _marker: std::marker::PhantomData, } diff --git a/packages/pynumaflow-lite/src/reduce/server.rs b/packages/pynumaflow-lite/src/reduce/server.rs index dc19de02..68d35762 100644 --- a/packages/pynumaflow-lite/src/reduce/server.rs +++ b/packages/pynumaflow-lite/src/reduce/server.rs @@ -107,21 +107,19 @@ impl reduce::Reducer for PyReduceRunner { // Ensure forwarder completes let _ = forwarder.await; - let messages = Python::attach(|py| { + Python::attach(|py| { // Expect Messages; also allow a single Message for convenience if let Ok(msgs) = result.extract::(py) { msgs.messages .into_iter() - .map(|m| reduce::Message::from(m)) + .map(reduce::Message::from) .collect::>() } else if let Ok(single) = result.extract::(py) { vec![single.into()] } else { vec![] } - }); - - messages + }) } } @@ -144,20 +142,18 @@ pub(super) async fn start( let obj = py_creator.bind(py); // Check if it's a function or coroutine function using inspect module let inspect = py.import("inspect").ok()?; - if let Ok(is_func) = inspect.call_method1("isfunction", (obj,)) { - if let Ok(result) = is_func.extract::() { - if result { - return Some(true); - } - } + if let Ok(is_func) = inspect.call_method1("isfunction", (obj,)) + && let Ok(result) = is_func.extract::() + && result + { + return Some(true); } // Also check for coroutine function - if let Ok(is_coro) = inspect.call_method1("iscoroutinefunction", (obj,)) { - if let Ok(result) = is_coro.extract::() { - if result { - return Some(true); - } - } + if let Ok(is_coro) = inspect.call_method1("iscoroutinefunction", (obj,)) + && let Ok(result) = is_coro.extract::() + && result + { + return Some(true); } Some(false) }) @@ -194,7 +190,7 @@ pub(super) async fn start( // if not finished, abort it if !sig_handle.is_finished() { println!("Aborting signal handler"); - let _ = sig_handle.abort(); + sig_handle.abort(); } result diff --git a/packages/pynumaflow-lite/src/reducestream/server.rs b/packages/pynumaflow-lite/src/reducestream/server.rs index 9e406179..3d11b23f 100644 --- a/packages/pynumaflow-lite/src/reducestream/server.rs +++ b/packages/pynumaflow-lite/src/reducestream/server.rs @@ -164,7 +164,7 @@ pub(super) async fn start( // if not finished, abort it if !sig_handle.is_finished() { println!("Aborting signal handler"); - let _ = sig_handle.abort(); + sig_handle.abort(); } result diff --git a/packages/pynumaflow-lite/src/session_reduce/server.rs b/packages/pynumaflow-lite/src/session_reduce/server.rs index 51438eae..e6e3266f 100644 --- a/packages/pynumaflow-lite/src/session_reduce/server.rs +++ b/packages/pynumaflow-lite/src/session_reduce/server.rs @@ -198,7 +198,7 @@ pub(super) async fn start( // if not finished, abort it if !sig_handle.is_finished() { println!("Aborting signal handler"); - let _ = sig_handle.abort(); + sig_handle.abort(); } result diff --git a/packages/pynumaflow-lite/src/sideinput/server.rs b/packages/pynumaflow-lite/src/sideinput/server.rs index 7d6f3cfb..ca130bbf 100644 --- a/packages/pynumaflow-lite/src/sideinput/server.rs +++ b/packages/pynumaflow-lite/src/sideinput/server.rs @@ -29,10 +29,7 @@ impl sideinput::SideInputer for PySideInputRunner { let result = fut.await.unwrap(); - let response = Python::attach(|py| { - let response: Response = result.extract(py).unwrap(); - response - }); + let response: Response = Python::attach(|py| result.extract(py).unwrap()); if response.broadcast { Some(response.value) diff --git a/packages/pynumaflow-lite/src/sink/mod.rs b/packages/pynumaflow-lite/src/sink/mod.rs index 6ccf5fb0..5ee344cb 100644 --- a/packages/pynumaflow-lite/src/sink/mod.rs +++ b/packages/pynumaflow-lite/src/sink/mod.rs @@ -383,6 +383,7 @@ pub struct Datum { } impl Datum { + #[allow(clippy::too_many_arguments)] fn new( keys: Vec, value: Vec, diff --git a/packages/pynumaflow-lite/src/sink/server.rs b/packages/pynumaflow-lite/src/sink/server.rs index d971d514..34466d2d 100644 --- a/packages/pynumaflow-lite/src/sink/server.rs +++ b/packages/pynumaflow-lite/src/sink/server.rs @@ -43,10 +43,7 @@ impl sink::Sinker for PySinkRunner { // Ensure forwarder completes let _ = forwarder.await; - let responses = Python::attach(|py| { - let x: crate::sink::Responses = result.extract(py).unwrap(); - x - }); + let responses: crate::sink::Responses = Python::attach(|py| result.extract(py).unwrap()); responses .responses diff --git a/packages/pynumaflow-lite/src/source/server.rs b/packages/pynumaflow-lite/src/source/server.rs index f47540e9..103105c3 100644 --- a/packages/pynumaflow-lite/src/source/server.rs +++ b/packages/pynumaflow-lite/src/source/server.rs @@ -25,11 +25,9 @@ impl numaflow::source::Sourcer for PySourceRunner { let py_handler = self.py_handler.clone(); // Call read_handler(request) -> AsyncIterator[Message] - let result = py_handler + py_handler .call_method1(py, "read_handler", (read_request,)) - .expect("failed to call read_handler"); - - result + .expect("failed to call read_handler") }); // Create a stream from the Python AsyncIterator diff --git a/packages/pynumaflow-lite/src/sourcetransform/server.rs b/packages/pynumaflow-lite/src/sourcetransform/server.rs index c554074b..31ee6b7e 100644 --- a/packages/pynumaflow-lite/src/sourcetransform/server.rs +++ b/packages/pynumaflow-lite/src/sourcetransform/server.rs @@ -83,7 +83,7 @@ pub(super) async fn start( // if not finished, abort it if !sig_handle.is_finished() { println!("Aborting signal handler"); - let _ = sig_handle.abort(); + sig_handle.abort(); } result diff --git a/packages/pynumaflow-lite/tests/bin/batchmap.rs b/packages/pynumaflow-lite/tests/bin/batchmap.rs index 88fb697e..5eeb1ac4 100644 --- a/packages/pynumaflow-lite/tests/bin/batchmap.rs +++ b/packages/pynumaflow-lite/tests/bin/batchmap.rs @@ -102,7 +102,7 @@ async fn main() -> Result<(), Box> { // We'll take the first result's value. let value = r .results - .get(0) + .first() .map(|res| res.value.clone()) .unwrap_or_default(); let id = r.id.clone(); diff --git a/packages/pynumaflow-lite/tests/bin/mapstream.rs b/packages/pynumaflow-lite/tests/bin/mapstream.rs index 0d0ea9ed..5929b8c8 100644 --- a/packages/pynumaflow-lite/tests/bin/mapstream.rs +++ b/packages/pynumaflow-lite/tests/bin/mapstream.rs @@ -75,7 +75,7 @@ async fn main() -> Result<(), Box> { assert!(maybe.is_some()); let resp = maybe.unwrap(); // Each MapResponse carries results; we take the first - if let Some(first) = resp.results.get(0) { + if let Some(first) = resp.results.first() { got.push(first.value.clone()); } } diff --git a/packages/pynumaflow-lite/tests/bin/reducestream.rs b/packages/pynumaflow-lite/tests/bin/reducestream.rs index b8d606db..8868a123 100644 --- a/packages/pynumaflow-lite/tests/bin/reducestream.rs +++ b/packages/pynumaflow-lite/tests/bin/reducestream.rs @@ -118,23 +118,19 @@ async fn main() -> Result<(), Box> { let mut message_count = 0; let mut found_eof = false; - loop { - if let Some(r) = resp.message().await? { - if let Some(res) = r.result { - assert!(!res.value.is_empty()); - message_count += 1; - println!( - "Received message {}: {:?}", - message_count, - String::from_utf8_lossy(&res.value) - ); - } - if r.eof { - found_eof = true; - println!("Received EOF"); - break; - } - } else { + while let Some(r) = resp.message().await? { + if let Some(res) = r.result { + assert!(!res.value.is_empty()); + message_count += 1; + println!( + "Received message {}: {:?}", + message_count, + String::from_utf8_lossy(&res.value) + ); + } + if r.eof { + found_eof = true; + println!("Received EOF"); break; } } diff --git a/packages/pynumaflow-lite/tests/bin/source.rs b/packages/pynumaflow-lite/tests/bin/source.rs index 460fb4c1..65afaa53 100644 --- a/packages/pynumaflow-lite/tests/bin/source.rs +++ b/packages/pynumaflow-lite/tests/bin/source.rs @@ -122,10 +122,10 @@ async fn read_messages( let mut messages = Vec::new(); while let Some(response) = response_stream.message().await? { - if let Some(status) = response.status { - if status.eot { - break; - } + if let Some(status) = response.status + && status.eot + { + break; } if let Some(result) = response.result { messages.push(result); From 8ee1e6d0098d400c7bdbedaeb0ad316ee327abdd Mon Sep 17 00:00:00 2001 From: Vaibhav Tiwari Date: Fri, 27 Mar 2026 23:42:23 -0400 Subject: [PATCH 10/14] chore: update active partitions handler doc comment Signed-off-by: Vaibhav Tiwari --- packages/pynumaflow/pynumaflow/sourcer/_dtypes.py | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py b/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py index ab96655d..1f036d86 100644 --- a/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py +++ b/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py @@ -301,7 +301,6 @@ async def active_partitions_handler(self) -> PartitionsResponse: """ Returns the active partitions associated with the source, used by the platform to determine the partitions to which the watermark should be published. - Falls back to partitions_handler() if not overridden. """ pass From e28676977d5861782fffbf5c6ecec25473e81436 Mon Sep 17 00:00:00 2001 From: Vaibhav Tiwari Date: Sat, 28 Mar 2026 00:04:41 -0400 Subject: [PATCH 11/14] chore: fix SyncSourceError test class to implement active_partitions_handler Signed-off-by: Vaibhav Tiwari --- packages/pynumaflow/tests/source/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pynumaflow/tests/source/utils.py b/packages/pynumaflow/tests/source/utils.py index ddd9930a..d5197452 100644 --- a/packages/pynumaflow/tests/source/utils.py +++ b/packages/pynumaflow/tests/source/utils.py @@ -108,7 +108,7 @@ def nack_handler(self, nack_request: NackRequest): def pending_handler(self) -> PendingResponse: return PendingResponse(count=10) - def partitions_handler(self) -> PartitionsResponse: + def active_partitions_handler(self) -> PartitionsResponse: return PartitionsResponse(partitions=mock_partitions()) From 84d80308b3631fdd014fc6d43cb08c326bc1f92f Mon Sep 17 00:00:00 2001 From: Vaibhav Kant Tiwari Date: Sat, 28 Mar 2026 12:46:06 -0400 Subject: [PATCH 12/14] Update packages/pynumaflow/pynumaflow/sourcer/_dtypes.py Co-authored-by: Vigith Maurice Signed-off-by: Vaibhav Tiwari --- packages/pynumaflow/pynumaflow/sourcer/_dtypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py b/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py index 1f036d86..f9e9bf78 100644 --- a/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py +++ b/packages/pynumaflow/pynumaflow/sourcer/_dtypes.py @@ -306,7 +306,7 @@ async def active_partitions_handler(self) -> PartitionsResponse: async def total_partitions_handler(self) -> int | None: """ - Optional. Returns the total number of partitions in the source. + Returns the total number of partitions in the source. Used by the platform for watermark progression to know when all processors have reported in. Returns None by default, indicating the source does not report total partitions. From 69369ac79b430293ee15afd167f542cc2429c44e Mon Sep 17 00:00:00 2001 From: Vaibhav Tiwari Date: Sat, 28 Mar 2026 13:09:39 -0400 Subject: [PATCH 13/14] chore: fix linting Signed-off-by: Vaibhav Tiwari --- .../pynumaflow/sourcer/servicer/async_servicer.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/pynumaflow/pynumaflow/sourcer/servicer/async_servicer.py b/packages/pynumaflow/pynumaflow/sourcer/servicer/async_servicer.py index d68a62cf..77ca94cc 100644 --- a/packages/pynumaflow/pynumaflow/sourcer/servicer/async_servicer.py +++ b/packages/pynumaflow/pynumaflow/sourcer/servicer/async_servicer.py @@ -303,9 +303,9 @@ async def PartitionsFn( return source_pb2.PartitionsResponse( result=source_pb2.PartitionsResponse.Result(partitions=[]) ) - result = source_pb2.PartitionsResponse.Result(partitions=partitions.partitions) - if total_partitions is not None: - result.total_partitions = total_partitions + result = source_pb2.PartitionsResponse.Result( + partitions=partitions.partitions, total_partitions=total_partitions + ) return source_pb2.PartitionsResponse(result=result) def clean_background(self, task): From 9f447257a826d8248d4408ae312221418a66ea1f Mon Sep 17 00:00:00 2001 From: Vaibhav Tiwari Date: Sat, 28 Mar 2026 13:10:03 -0400 Subject: [PATCH 14/14] chore: fix linting Signed-off-by: Vaibhav Tiwari --- packages/pynumaflow/tests/source/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pynumaflow/tests/source/utils.py b/packages/pynumaflow/tests/source/utils.py index a5cbff81..a744e07b 100644 --- a/packages/pynumaflow/tests/source/utils.py +++ b/packages/pynumaflow/tests/source/utils.py @@ -87,7 +87,7 @@ async def active_partitions_handler(self) -> PartitionsResponse: async def total_partitions_handler(self) -> int | None: return 10 - + def read_req_source_fn() -> ReadRequest: request = source_pb2.ReadRequest.Request( num_records=10,