Skip to main content

Python DI/IoC container

Project description

Python DI / IoC container

Dependency injection means giving an object its instance variables.

-- James Shore, Dependency Injection Demystified

Initially it was created for AWS Lambda Functions to simplify development with loose coupling component and improved testing capabilities.

Inspiration comes from python:design_patterns:inversion_of_control summary article.

This modules is an optimized version of a container used in p3.4.advanced-di-ioc section of my lambda-modular-python MOB session @cloudreach.

Usage

Orchestrate container in ioc.py file:

# ioc.py
import pydioc
import boto3
import some_sdk
from . import services

def build_container(ssm_param_api_key: str, ddb_status_table: str, format_type: str) -> pydioc.Container:
    return pydioc.Container(
        ("_boto3_session", boto3.Session),
        ("lambda_context", pydioc.ContextProxy),

        ("_api_key_loader", services.api_key_loader, ["_boto3_session", lambda: ssm_param_api_key]),
        ("_status_updater", services.status_updater, ["_boto3_session", "lambda_context", lambda: ddb_status_table]),

        ("_sdk_data_formatter", some_sdk.FormatterFactory, [lambda: format_type]),
        ("_sdk_client_factory", services.sdk_client_factory, ["_api_key_loader"]),

        ("_sdk_data_transfer", services.sdk_data_transfer, ["_sdk_client_factory", "_sdk_data_formatter", "lambda_context"]),

        ("event_handler", services.event_handler, ["_sdk_data_transfer", "_status_updater"]),
    )

Define services in services.py file:

# services.py
import boto3
import some_sdk

# ...

def api_key_loader(session: boto3.Session, ssm_param_api_key: str):
    assert ssm_param_api_key, 'expecting non empty api_key param'

    def _api_key_loader():
        # very simplified code
        return session.client('ssm').get_parameter(Name=ssm_param_api_key)["Parameter"]["Value"]

    return _api_key_loader

def sdk_client_factory(load_api_key: api_key_loader):
    def _sdk_client_factory(client_type):
        # very simplified code
        api_key = load_api_key()
        if client_type == 'User':
            return some_sdk.user.Client(api_key)
        raise ValueError(f"unknown client type: {client_type}")
    return sdk_client_factory

def sdk_data_transfer(client_factory: sdk_client_factory, formatter: some_sdk.Formatter, context: object):
    def _sdk_data_transfer(payload: dict)
        # very simplified code
        client = client_factory(payload['type'])
        client.publish(formatter.format(payload['body']), handler=context.invoked_function_arn)
    return _sdk_data_transfer

# ...

Configure and run in main.py file:

# main.py
import os
from . import ioc

init_error = None

try:
    container = ioc.build_container(
        ssm_param_api_key=os.environ.get("SSM_PARAM_API_KEY"),
        ddb_status_table=os.environ.get("DDB_STATUS_TABLE"),
        format_type=os.environ.get("FORMAT_TYPE", "YAML"),
    )
except Exception as ex:
    init_error = ex


def lambda_handler(event: dict, context: object):
    if init_error:
        raise init_error

    container.lambda_context(context)

    return container.event_handler(event)

In this example container would be compiled once per Lambda Function life cycle, while lambda_handler processes incoming requests sequentially, until it dies after idle timeout.

Project details


Release history Release notifications | RSS feed

This version

0.1

Download files

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

Source Distribution

pydioc-0.1.tar.gz (4.1 kB view details)

Uploaded Source

File details

Details for the file pydioc-0.1.tar.gz.

File metadata

  • Download URL: pydioc-0.1.tar.gz
  • Upload date:
  • Size: 4.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.1.3 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.7.7

File hashes

Hashes for pydioc-0.1.tar.gz
Algorithm Hash digest
SHA256 c266f55614bec72f085d69c2d071081d825a3e00e368facbeda7047b9acfddca
MD5 34123637ba32f1fd313f9d46b5ab7469
BLAKE2b-256 93bbb2817bc22aa7eb17eaf0d6502833aeb9da7d1b92b881b7523593281e8e0b

See more details on using hashes here.

Supported by

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