Metadata-Version: 2.1
Name: harness
Version: 0.1.0rc2
Summary: Language-agnostic microservices boilerplate as a code
Home-page: https://github.com/vmagamedov/harness
Author: Vladimir Magamedov
Author-email: vladimir@magamedov.com
License: BSD-3-Clause
Description: Harness (proof-of-concept)
        ==========================
        
        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):
        
        .. code-block:: protobuf
        
          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.options).input = "python/asyncpg.v1:Connection"];
            harness.grpc.Channel taskqueue = 3 [(harness.options).input = "python/grpclib.v1:Channel"];
            harness.grpc.Endpoint listen = 4 [(harness.options).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):
        
        .. code-block:: yaml
        
          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:
        
        .. code-block:: python3
        
          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:
        
        .. code-block:: python3
        
          @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):
        
        .. code-block:: python3
        
          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:
        
        .. code-block:: console
        
          $ 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:
        
        .. code-block:: console
        
          $ harness svc:main config.yaml
        
Platform: UNKNOWN
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3 :: Only
Requires-Python: >=3.7
Description-Content-Type: text/x-rst
