Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ VERSION_FILES := Cargo.toml \
bindings/golang/Cargo.toml \
bindings/python/Cargo.toml \
bindings/python/pyproject.toml \
bindings/python/src/smg/version.py
bindings/python/src/smg/version.py \
grpc_client/python/pyproject.toml \
grpc_client/python/smg_grpc_proto/__init__.py

show-version: ## Show current version across all files
@echo "Current versions:"
Expand All @@ -148,6 +150,8 @@ show-version: ## Show current version across all files
@echo " bindings/python/Cargo.toml: $$(grep -m1 '^version = ' bindings/python/Cargo.toml | sed 's/version = "\(.*\)"/\1/')"
@echo " bindings/python/pyproject.toml: $$(grep -m1 '^version = ' bindings/python/pyproject.toml | sed 's/version = "\(.*\)"/\1/')"
@echo " bindings/python/.../version.py: $$(grep '__version__' bindings/python/src/smg/version.py | sed 's/__version__ = "\(.*\)"/\1/')"
@echo " grpc_client/python/pyproject.toml: $$(grep -m1 '^version = ' grpc_client/python/pyproject.toml | sed 's/version = "\(.*\)"/\1/')"
@echo " grpc_client/python/.../__init__.py: $$(grep '__version__' grpc_client/python/smg_grpc_proto/__init__.py | sed 's/__version__ = "\(.*\)"/\1/')"

bump-version: ## Bump version across all files (usage: make bump-version VERSION=0.3.3)
@if [ -z "$(VERSION)" ]; then \
Expand All @@ -169,12 +173,18 @@ bump-version: ## Bump version across all files (usage: make bump-version VERSION
@sed -i.bak 's/^version = ".*"/version = "$(VERSION)"/' bindings/python/pyproject.toml && rm -f bindings/python/pyproject.toml.bak
@# Update version.py
@sed -i.bak 's/__version__ = ".*"/__version__ = "$(VERSION)"/' bindings/python/src/smg/version.py && rm -f bindings/python/src/smg/version.py.bak
@# Update grpc_client/python/pyproject.toml
@sed -i.bak 's/^version = ".*"/version = "$(VERSION)"/' grpc_client/python/pyproject.toml && rm -f grpc_client/python/pyproject.toml.bak
@# Update grpc_client/python/smg_grpc_proto/__init__.py
@sed -i.bak 's/__version__ = ".*"/__version__ = "$(VERSION)"/' grpc_client/python/smg_grpc_proto/__init__.py && rm -f grpc_client/python/smg_grpc_proto/__init__.py.bak
@echo "Version updated to $(VERSION) in all files:"
@echo " - Cargo.toml"
@echo " - bindings/golang/Cargo.toml"
@echo " - bindings/python/Cargo.toml"
@echo " - bindings/python/pyproject.toml"
@echo " - bindings/python/src/smg/version.py"
@echo " - grpc_client/python/pyproject.toml"
@echo " - grpc_client/python/smg_grpc_proto/__init__.py"
@echo ""
@echo "Verify with: make show-version"

Expand Down
7 changes: 7 additions & 0 deletions grpc_client/python/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Generated stubs (created at build time)
smg_grpc_proto/generated/

# Build artifacts
dist/
*.egg-info/
build/
39 changes: 39 additions & 0 deletions grpc_client/python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# smg-grpc-proto

Protocol Buffer definitions for SMG (Shepherd Model Gateway) gRPC services.

This package provides the Python gRPC stubs for:
- **SGLang** scheduler service
- **vLLM** engine service
- **TRT-LLM** service

## Installation

```bash
pip install smg-grpc-proto
```

## Usage

```python
from smg_grpc_proto import sglang_scheduler_pb2, sglang_scheduler_pb2_grpc
from smg_grpc_proto import vllm_engine_pb2, vllm_engine_pb2_grpc
from smg_grpc_proto import trtllm_service_pb2, trtllm_service_pb2_grpc
```

## Development

The proto files are located in `grpc_client/proto/` in the SMG repository. Python stubs are generated at build time using `grpcio-tools`.

To build locally:

```bash
# From repo root
mkdir -p grpc_client/python/smg_grpc_proto/proto
cp grpc_client/proto/*.proto grpc_client/python/smg_grpc_proto/proto/
pip install -e grpc_client/python/
Comment thread
CatherineSue marked this conversation as resolved.
Resolved
```

## License

Apache-2.0
40 changes: 40 additions & 0 deletions grpc_client/python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[build-system]
requires = ["setuptools>=68.0", "grpcio-tools>=1.62.0"]
build-backend = "setuptools.build_meta"

[project]
name = "smg-grpc-proto"
version = "0.3.2"
description = "SMG gRPC proto definitions for SGLang, vLLM, and TRT-LLM"
requires-python = ">=3.10"
dependencies = [
"grpcio>=1.62.0",
"protobuf>=5.26.0",
]
readme = "README.md"
license = { text = "Apache-2.0" }
authors = [
{name = "Simo Lin", email = "linsimo.mark@gmail.com"},
{name = "Chang Su", email = "mckvtl@gmail.com"},
{name = "Keyang Ru", email = "rukeyang@gmail.com"}
]
classifiers = [
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"License :: OSI Approved :: Apache Software License",
"Operating System :: OS Independent",
]

[project.urls]
Homepage = "https://github.com/lightseekorg/smg"
Repository = "https://github.com/lightseekorg/smg"

[tool.setuptools.packages.find]
where = ["."]
include = ["smg_grpc_proto*"]

[tool.setuptools.package-data]
smg_grpc_proto = ["proto/*.proto", "generated/*.py"]
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
104 changes: 104 additions & 0 deletions grpc_client/python/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
"""
Custom setup.py to generate protobuf stubs at build time.
The generated files are NOT committed to git — they're created fresh during pip install.
"""
from pathlib import Path

from setuptools import setup
from setuptools.command.build_py import build_py
from setuptools.command.develop import develop


def compile_grpc_protos():
"""Generate Python gRPC stubs from .proto files."""
package_dir = Path(__file__).parent
proto_dir = package_dir / "smg_grpc_proto" / "proto"
output_dir = package_dir / "smg_grpc_proto" / "generated"

output_dir.mkdir(parents=True, exist_ok=True)
(output_dir / "__init__.py").write_text(
'"""Auto-generated protobuf stubs. Do not edit."""\n'
)

proto_files = list(proto_dir.glob("*.proto"))
if not proto_files:
print("Warning: No .proto files found in", proto_dir)
return
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

# Use grpc_tools.protoc Python API (same approach as vLLM)
try:
from grpc_tools import protoc

args = [
"grpc_tools.protoc",
f"--proto_path={proto_dir}",
f"--python_out={output_dir}",
f"--grpc_python_out={output_dir}",
f"--pyi_out={output_dir}", # Generate type stubs
] + [str(f) for f in proto_files]

print(f"Generating protobuf stubs from {len(proto_files)} proto files...")
result = protoc.main(args)

if result != 0:
raise RuntimeError(f"protoc returned non-zero exit code: {result}")

except ImportError:
raise RuntimeError(
"grpcio-tools not installed. Install with: pip install grpcio-tools"
)

# Fix imports in generated files (grpcio-tools generates absolute imports)
# Also add mypy ignore-errors comment for generated code
mypy_header = "# mypy: ignore-errors\n"

for py_file in output_dir.glob("*_pb2*.py"):
content = py_file.read_text()

# Fix imports to be relative
for proto_file in proto_files:
module_name = proto_file.stem + "_pb2"
content = content.replace(
f"import {module_name}", f"from . import {module_name}"
)

# Add mypy ignore-errors if not already present
if not content.startswith("# mypy:"):
content = mypy_header + content

py_file.write_text(content)

# Also add mypy header to .pyi files
for pyi_file in output_dir.glob("*_pb2*.pyi"):
content = pyi_file.read_text()
if not content.startswith("# mypy:"):
pyi_file.write_text(mypy_header + content)

generated_count = len(list(output_dir.glob("*.py"))) + len(
list(output_dir.glob("*.pyi"))
)
print(f"Generated {generated_count} files (including type stubs)")


class BuildPyWithProto(build_py):
"""Custom build_py that generates protobuf stubs before building."""

def run(self):
compile_grpc_protos()
super().run()


class DevelopWithProto(develop):
"""Custom develop that generates protobuf stubs for editable installs."""

def run(self):
compile_grpc_protos()
super().run()


setup(
cmdclass={
"build_py": BuildPyWithProto,
"develop": DevelopWithProto,
}
)
27 changes: 27 additions & 0 deletions grpc_client/python/smg_grpc_proto/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""SMG gRPC Proto - Protocol definitions for SGLang, vLLM, and TRT-LLM."""

__version__ = "0.3.2"

# Re-export generated modules for convenient access
# These imports will work after the package is built (stubs generated at build time)
try:
from smg_grpc_proto.generated import (
sglang_scheduler_pb2,
sglang_scheduler_pb2_grpc,
trtllm_service_pb2,
trtllm_service_pb2_grpc,
vllm_engine_pb2,
vllm_engine_pb2_grpc,
)

__all__ = [
"sglang_scheduler_pb2",
"sglang_scheduler_pb2_grpc",
"vllm_engine_pb2",
"vllm_engine_pb2_grpc",
"trtllm_service_pb2",
"trtllm_service_pb2_grpc",
]
except ImportError:
# During development/build, generated modules may not exist yet
__all__ = []
1 change: 1 addition & 0 deletions grpc_client/python/smg_grpc_proto/proto
Loading