Microservice framework for Python
Nameko is a flexible framework for creating microservices in Python. It’s easy to get started but built on powerful concepts.
-
Mix & Match Protocols
Microservices need to do more than just HTTP.
Nameko lets you publish and consume asynchronous messages, with any protocol you choose. Use the built-in extensions, leverage the community, or build your own.
-
Focus on Application Logic
Write regular Python methods and classes to implement your service.
Connections, transports and concurrency are hidden behind clean abstractions.
-
Helpfully Opinionated
Nameko helps you to write service that separate concerns, and are easy to reason about and test.
Examples
-
RPC
from nameko.rpc import rpc class MathService: name = "math" @rpc def add(self, *args: int): return sum(args)
- This example requires a RabbitMQ broker to be running. See the installation page for help if you need it.
-
This is an example of a trivial RPC method. RPC is a simple way to expose remote methods with extremely low boilerplate.
RPC methods can be called by other services, with standalone clients, or with the
nameko shell
:- The
n
global is a helper in thenameko shell
. Itsrpc
attribute is a client that you can use to call RPC methods on any service in the current cluster.
- The
-
HTTP
from nameko.web.handlers import http class MathService: name = "math" @http("POST", "/add") def add(self, request): return 200, f"{sum(request.json)}"
-
It’s useful for services to also be able to handle HTTP requests.
Nameko includes Flask-like HTTP entrypoint for this. It’s built on the same WSGI server as Flask, so has similar syntax.
-
Events
from nameko.events import EventDispatcher, event_handler from nameko.timer import timer import random class DispatcherService: name = "dispatcher" dispatch = EventDispatcher() # (1)! @timer(interval=1) def dispatching_method(self): self.dispatch("random_number", random.random()) # (2)! class ListenerService: name = "listener" @event_handler("dispatcher", "random_number") # (3)! def handle_event(self, payload): print("listener received:", payload)
- Thing
- Thang
- Thong
- This example defines two services in the same module and runs them together. This isn’t recommended for production scenarios, but it’s convenient during tests and demos.
-
Nameko’s event system is an effective way to decouple microservices from each other.
Rather than using request-response calls to fetch data, events provide a one-way, decoupled, and buffered communication mechanism to broadcast data instead.
This example shows to services that communicate via events. Using the
timer
entrypoint, thedispatcher
service emits an event containing a random number every second.The
listener
service receives the events and prints the output:listener received: 0.7242024270508401 listener received: 0.30384214204892646 listener received: 0.22763038056327844 listener received: 0.32263365251353326
If the
listener
is stopped and later resumed, it will receive all the events dispatched in the mean time.
-
gRPC
from nameko_grpc.entrypoint import Grpc import grpc helloworld_pb2, helloworld_pb2_grpc = grpc.protos_and_services( "helloworld.proto" #(1)! ) grpc = Grpc.implementing(helloworld_pb2_grpc.GreeterStub) class Greeter: name = "greeter" @grpc def say_hello(self, request, context): return helloworld_pb2.HelloReply( message=f"Hello, {request.name}!" ) @grpc def say_hello_again(self, request, context): return helloworld_pb2.HelloReply( message=f"Hello again, {request.name}!" )
- Runs the codegen at runtime, for convenience.
-
Talk about this example
-
Database
from nameko.events import EventDispatcher, event_handler from nameko.web.handlers import http class ServiceA: """ Event dispatching service. """ name = "service_a" dispatch = EventDispatcher() @http("PUT", "/dispatch") def dispatching_method(self, request): # business logic lives here self.dispatch("event_type", request.body) class ServiceB: """ Event listening service. """ name = "service_b" @event_handler("service_a", "event_type") def handle_event(self, payload): # business logic lives here print("service b received:", payload)
-
Talk about this example
Get Started
Why Nameko?
Installation
Key Concepts
Tutorial