Sonora

raw JSON →
0.2.3 verified Sat May 09 auth: no python

A WSGI and ASGI compatible gRPC-web implementation. Version 0.2.3 supports Python >=3.7,<4.0. Provides middleware for integrating gRPC-web clients with Python web frameworks like Flask (WSGI) or Starlette (ASGI).

pip install sonora
error ImportError: cannot import name 'SonoraWSGIMiddleware' from 'sonora'
cause Attempting to import from the top-level package instead of the wsgi submodule.
fix
Use: from sonora.wsgi import SonoraWSGIMiddleware
error TypeError: handler() missing 1 required positional argument: 'request'
cause Your handler function does not accept the request argument expected by Sonora.
fix
Define the handler with at least one argument, e.g., def my_handler(request):
error AttributeError: module 'sonora' has no attribute 'client'
cause Importing 'import sonora.client' incorrectly; 'client' is a module, not a subpackage.
fix
Use: from sonora import client
error sonora.exceptions.GRPCError: 404 Not Found
cause The gRPC service name and method are not recognized; likely the request path does not match the expected pattern.
fix
Ensure the gRPC-web request path follows the format '/package.Service/Method'. Check the handler implementation.
gotcha Sonora requires an actual gRPC handler; it does not auto-generate stubs. You must define a handler that processes gRPC-web requests.
fix Implement a callable handler that matches the gRPC service definition.
gotcha Sonora does not support streaming gRPC (both client and server streaming). Only unary calls are supported.
fix Use other libraries like grpcio-web or grpc-gateway for streaming.
deprecated Sonora's API may change in future versions; the project is experimental and not widely maintained.
fix Monitor the repository for updates or consider alternatives like grpclib or grpc-web.
gotcha When using ASGI, SonoraASGIMiddleware expects a handler that returns an HTTP response; it does not integrate with Starlette's request/response cycle directly.
fix Ensure the handler returns a dict with status, headers, and body.

Basic WSGI integration with Flask.

from flask import Flask
from sonora.wsgi import SonoraWSGIMiddleware

app = Flask(__name__)

# Placeholder gRPC handler (replace with actual implementation)
def my_grpc_handler(request):
    return {}

sonora_app = SonoraWSGIMiddleware(app, handler=my_grpc_handler)

if __name__ == '__main__':
    from wsgiref.simple_server import make_server
    server = make_server('localhost', 5000, sonora_app)
    server.serve_forever()