Python Dependency Injection

Official Repo

Introduction

As the name suggest, this application is for injecting dependencies into other objects. It's much similar to Java Spring Framework.

Show me the code

Create a test bean class for custom dependency injection

# Create a class for bean
class TestBean:
    def __init__(self, name):
        self.name = name

Define a bean method to return a Bean Object using @Bean.

NOTE: : The bean method parameters and return type should have the class name of the dependent and return type object, to let it know which class object should be injected and returned.

# Create a bean object for Autowiring   
@Bean()
def getTestBean() -> TestBean:
    return TestBean("Test 123")

Test your dependency injection, using @Autowired.

NOTE: : The autowired method parameters should have the class name of the Dependent Object, to let it know which class object should be injected.

testBean = None

# Autowire the dependency
@Autowired()
def setTestBean(bean: TestBean):
    global testBean
    print(bean)
    testBean = bean

if __name__ == "__main__":
    app = AppInitilizer()  # Create a instance for AppInitializer
    app.componentScan("test_module") # Add package to scan for any component or bean

    app.run() # Call run methods to inject beans
    print(testBean.name)
    print(type(testBean))

Advance: Lookup at CNDI

External yaml configurations

Using cndi users can configure the application on different environemnt setting, using the rcn.profile attribute in the yaml file. Checkout the below yaml configuration

rcn.profile: local
mqtt:
    broker: localhost
    port: 1883

---
rcn.profile: dev
mqtt:
    broker: dev_mqtt_adderss.com
    port: 11883

The above yaml has the configurations for two environment local and dev, with different configuration for mqtt brokers. Below is the code for how to use it.

from cndi.env import loadEnvFromFile, getContextEnvironment

# First step: set the profile, this can be set directly to environment RCN_ENVS_CONFIG.active.profile or using os package

RCN_ENVS_CONFIG = 'RCN_ENVS_CONFIG'
os.environ[f"{RCN_ENVS_CONFIG}.active.profile"] = "local" # Set profile to use

# Load yaml file
loadEnvFromFile("path/to/yaml")

server = getContextEnvironment("mqtt.broker") # Get Property Value
port = int(getContextEnvironment("mqtt.port")) # Get Property Value

Flask Application

Let's create a flask app to get the working on CNDI in depth (well below video doesn't go that far but gives some understanding). In this example we will create a Flask app which will listen at /events.

Find the repository here.

NOTE: : The above app requires a mqtt broker running in background. Otherwise it will throw exception while calling connect method.

Route: /event will send a timestamp to mqtt topic defined in the

# Directory Structure
src/
  + ./beans/*/*.py          ->  Define beans in this modules and sub modules. 
  + ./app.py                ->  Main application.
  + ./configurations/*.yml  ->  YAML files to define external configurations.

Implementation of CNDI