- Notifications
You must be signed in to change notification settings - Fork0
The Python implementation of Connect
License
gaudiy/connect-python
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Connect is a simple, reliable, and interoperable RPC framework that combines the best of gRPC and REST. This Python implementation provides a clean, efficient way to build type-safe APIs with Protocol Buffers while maintaining excellent compatibility with existing HTTP infrastructure.
- Multi-protocol support: Serve Connect, gRPC and gRPC-Web clients from one endpoint
- Type Safety: Built on Protocol Buffers with automatic code generation
- HTTP ecosystem friendly: Works with standard HTTP/1.1+ and existing infrastructure
- Streaming: Full support for unary, client streaming, server streaming, and bidirectional streaming (half-duplex)
- Developer-friendly: Easy debugging with standard HTTP tools like curl
- Standard HTTP semantics: Meaningful status codes, cacheable GET requests for read-only RPCs
pip install connectrpc
- httpcore:https://github.com/tsubakiky/httpcore (auto-installed)
- hypercorn:https://github.com/tsubakiky/hypercorn (manual install for servers)
Requirements by protocol:
- Connect protocol: Standard PyPI versions work fine
- gRPC/gRPC-Web: Forked versions required (HTTP trailer support)
For server development install forked hypercorn:
pip install git+https://github.com/tsubakiky/hypercorn.git
Create a Protocol Buffer definition (ping.proto):
syntax="proto3";packageconnectrpc.ping.v1;messagePingRequest {stringmessage=1;}messagePingResponse {stringmessage=1;}servicePingService {rpcPing(PingRequest)returns (PingResponse);}
Install and use the Connect Python plugin to generate client and server code:
# Install the code generatorgo install github.com/gaudiy/connect-python/cmd/protoc-gen-connect-python@latest# Generate Python codeprotoc --plugin=$(go env GOPATH)/bin/protoc-gen-connect-python -I. --connect-python_out=. --connect-python_opt=paths=source_relative ping.proto
fromconnectrpc.connectimportUnaryRequest,UnaryResponsefromconnectrpc.handler_contextimportHandlerContextfromconnectrpc.middlewareimportConnectMiddlewarefromstarlette.applicationsimportStarlettefromstarlette.middlewareimportMiddlewarefromping_pb2importPingRequest,PingResponsefromping_connect_pb2importPingServiceHandler,create_PingService_handlersclassPingService(PingServiceHandler):asyncdefPing(self,request:UnaryRequest[PingRequest],context:HandlerContext )->UnaryResponse[PingResponse]:returnUnaryResponse(PingResponse(message=f"Pong:{request.message.message}") )# Create the ASGI appapp=Starlette(middleware=[Middleware(ConnectMiddleware,create_PingService_handlers(PingService()) ) ])
importasyncioimporthypercorn# Must be tsubakiky's fork!importhypercorn.asyncioif__name__=="__main__":config=hypercorn.Config()config.bind= ["localhost:8080"]asyncio.run(hypercorn.asyncio.serve(app,config))
fromconnectrpc.clientimportUnaryRequestfromconnectrpc.connection_poolimportAsyncConnectionPoolfromping_pb2importPingRequestfromping_connect_pb2importPingServiceClientasyncdefmain():asyncwithAsyncConnectionPool()aspool:client=PingServiceClient(pool=pool,base_url="http://localhost:8080" )request=UnaryRequest(PingRequest(message="Hello, Connect!"))response=awaitclient.Ping(request)print(f"Response:{response.message.message}")asyncio.run(main())
Connect Python supports all streaming patterns:
# Server streamingasyncdefGetUpdates(self,request,context):# Get the single request messagemessage=awaitrequest.single()asyncdefstream_updates():foriinrange(10):yieldUpdateResponse(message=f"Update{i} for{message.name}")returnStreamResponse(stream_updates())# Client streamingasyncdefSendData(self,request,context):sentences=""asyncformessageinrequest.messages:sentences+=message.datareturnStreamResponse(SummaryResponse(content=sentences))# Bidirectional streaming (half-duplex)asyncdefChat(self,request,context):# First, consume all client messagescollected_messages= []asyncformessageinrequest.messages:collected_messages.append(message.text)# Then, generate responses based on collected messagesasyncdefecho_messages():fori,msginenumerate(collected_messages):yieldChatResponse(message=f"Echo{i+1}:{msg}")returnStreamResponse(echo_messages())
Important
The current implementation of bidirectional streaming only supportshalf-duplex mode, where the server must fully consume the client's input stream before producing output.Full-duplex bidirectional streaming (where client and server can send messages simultaneously) is not yet supported but is planned for future releases.
This means:
- ✅Supported: Server processes all client messages, then sends responses
- ❌Not yet supported: True real-time bidirectional communication with simultaneous message exchange
For most use cases, half-duplex streaming is sufficient. If you need full-duplex streaming, consider using separate unary or streaming RPCs for now.
One server handles all client types:
- Connect: HTTP-friendly with standard tooling
- gRPC: Full compatibility with existing implementations
- gRPC-Web: Direct browser support, no proxy needed
- Plain HTTP: POST for RPCs, GET for read-only calls
Theexamples/ directory contains a complete implementation of an Eliza chatbot service demonstrating:
- Unary RPC calls
- Server streaming
- Client streaming
- Bidirectional streaming (half-duplex)
- Client and server implementations
Run the example:
cd examples# Start the serverpython server.py# In another terminal, run the clientpython client.py --unary# Unary callpython client.py --server-streaming# Server streamingpython client.py --client-streaming# Client streaming
- Python 3.13+
- Protocol Buffers compiler (
protoc) - Go (for the code generator)
- uv (recommended package manager)
Recommended: Useuv for package management. On macOS, you can install it withbrew install uv. For other platforms, see theuv documentation.
# Clone the repositorygit clone https://github.com/gaudiy/connect-python.gitcd connect-python# Install dependencies (using uv - recommended)uv sync# Run testspytest# Run conformance testscd conformance# Server conformance testsconnectconformance -vv --trace --conf ./server_config.yaml --mode server -- uv run python server_runner.py# Client conformance testsconnectconformance -vv --trace --conf ./client_config.yaml --mode client -- uv run python client_runner.py
- Forked
httpcoreauto-configured inpyproject.toml - Server development: Install forked hypercorn manually
- Client-only: No additional setup needed
- Connect only: Standard PyPI versions work
This project includes a Protocol Buffer plugin (protoc-gen-connect-python) written in Go that generates Python client and server code from.proto files.
We warmly welcome and greatly value contributions to the connectrpc. However, before diving in, we kindly request that you take a moment to review our Contribution Guidelines.
Additionally, please carefully read the Contributor License Agreement (CLA) before submitting your contribution to Gaudiy. By submitting your contribution, you are considered to have accepted and agreed to be bound by the terms and conditions outlined in the CLA, regardless of circumstances.
https://site.gaudiy.com/contributor-license-agreement
This project is licensed under the Apache 2.0 License - see theLICENSE file for details.
About
The Python implementation of Connect
Topics
Resources
License
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors2
Uh oh!
There was an error while loading.Please reload this page.