Skip to main content

Language-agnostic microservices boilerplate as a code

Project description

Language-agnostic microservices boilerplate as a code. You define service configuration and implementation, Harness takes care for it’s life cycle:

  • load configuration: read, validate

  • initialize environment: database and other outgoing connections

  • start servers/subscribers

  • graceful shutdown

Configuration

Harness uses Protocol Buffers as a configuration definition language (svc.proto file):

syntax = "proto3";

package cafe;

import "harness/options.proto";
import "harness/postgres.proto";
import "harness/grpc.proto";

message Configuration {
  bool debug = 1;
  harness.postgres.DSN db = 2 [(harness.input) = "python/asyncpg.v1:Connection"];
  harness.grpc.Channel taskqueue = 3 [(harness.input) = "python/grpclib.v1:Channel"];
  harness.grpc.Endpoint listen = 4 [(harness.output) = "python/grpclib.v1:Server"];
}

As you can see from this configuration, our service has:

  • debug mode

  • database connection

  • gRPC channel to the taskqueue service

  • gRPC server to serve incoming requests

We can provide values for this configuration using YAML file (config.yaml file):

db:
  value: postgres://postgres:postgres@db.cafe.svc.cluster.local:5432/coffee
taskqueue:
  host: taskqueue.platform.svc.cluster.local
  port: 50051
listen:
  host: 0.0.0.0
  port: 50051

Service Definition

Harness must be able to run your service. In order to do this you must provide a main function, it’s signature looks like this:

from svc_wires import WiresIn, WiresOut

async def main(wires_in: WiresIn) -> WiresOut:
    ...
    return WiresOut(...)

Where WiresIn and WiresOut are generated by the Harness from your service configuration:

@dataclass
class WiresIn:
    db: harness.resources.asyncpg.v1.Connection
    taskqueue: harness.resources.grpclib.v1.Channel

@dataclass
class WiresOut:
    listen: harness.resources.grpclib.v1.Server

When Harness runs your service, you receive already initialized environment in a WiresIn structure. All you have to do is to setup your request handler and return it with a WiresOut structure (svc.py file):

from harness.resources.grpclib.v1 import Server

from svc_grpc import CoffeeMachineBase

class CoffeeMachine(CoffeeMachineBase):
    ...

async def main(wires_in: WiresIn) -> WiresOut:
    print('Connection:', wires_in.db.connection)
    print('Channel:', wires_in.taskqueue.channel)
    server_resource = Server([
        CoffeeMachine(
            db=wires_in.db.connection,
            taskqueue=wires_in.taskqueue.channel,
        ),
    ])
    return WiresOut(listen=server_resource)

Files Generation

We use protoc compiler to generate boilerplate from your configuration:

$ protoc -I $HARNESS_PROTO --python_out=. --python_grpc_out=. --python_harness_out=. --mypy_out=. svc.proto

Where $HARNESS_PROTO is where to find Harness proto-files.

Runtime

Use harness command to run your service:

$ harness svc:main config.yaml

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

harness-0.1.0rc1.tar.gz (9.0 kB view details)

Uploaded Source

File details

Details for the file harness-0.1.0rc1.tar.gz.

File metadata

  • Download URL: harness-0.1.0rc1.tar.gz
  • Upload date:
  • Size: 9.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.40.2 CPython/3.7.3

File hashes

Hashes for harness-0.1.0rc1.tar.gz
Algorithm Hash digest
SHA256 307f51896591ca15850c22bf2bc42fe853957fc27e1faa11f34602de8fe63975
MD5 98eddcc59bfd435b9ebd2eb6aef7e9aa
BLAKE2b-256 44dcdab967f660f74890de9e189d1830307c6c94a1405c1c4bc9c34133613270

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page