πŸš€ Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more β†’
Socket
DemoInstallSign in
Socket

bindry

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bindry

Elegant Python Dependency Injection with Profile-Aware Configuration

0.1.2
PyPI
Maintainers
1

πŸ”—πŸ“š Bindry

Elegant Python Dependency Injection with Profile-Aware Configuration

PyPI version Python Support License: MIT

🌟 Overview

Bindry is a powerful yet intuitive dependency injection framework for Python that supports profile-based configuration, environment variable interpolation, and flexible component lifecycle management. It enables you to write more maintainable and testable applications by managing dependencies through configuration rather than hard-coding them.

🎯 Motivation

As a Spring developer, I was eager to explore the possibilities of dependency injection in Python. While Spring's robust ecosystem has been instrumental in shaping my understanding of modern software development, I found myself craving a framework that could leverage Python's unique strengths and flexibility. Bindry fills this gap by providing an elegant and intuitive solution for managing dependencies in Python applications.

✨ Features

  • πŸ—‚οΈ Profile-based configuration management
  • 🌐 Environment variable support with fallback values
  • πŸ“œ YAML and JSON configuration file support
  • βš™οΈ Constructor, method, and property injection
  • 🧩 Singleton and prototype scoping
  • πŸ” Type-based automatic dependency resolution
  • πŸ› οΈ Support for constructor arguments via configuration
  • 🏷️ Flexible component registration through decorators or configuration files

πŸ“¦ Installation

pip install bindry

πŸš€ Quick Start

1. Define Your Components

from bindry import component, Scope, autowired

# Define an interface
class MessageService:
    def send_message(self, msg: str): pass

# Implement the service
# Register the bean in application-context.yaml
class EmailService(MessageService):
    def send_message(self, msg: str):
        print(f"Sending email: {msg}")

# Use declarator to register the bean
@component(scope=Scope.SINGLETON)
class NotificationManager:
    # MessageService will be injected
    def __init__(self, message_service: MessageService):
        self.message_service = message_service

    def notify(self, message: str):
        self.message_service.send_message(message)

2. Configure Your Application

Create a application-context.yaml file:

profiles:
  default:
    beans:
      MessageService:
        bean_type: "myapp.services.MessageService"
        implementation: "myapp.services.EmailService"
        scope: "singleton"
        constructor_args:
          timeout: 30

  development:
    beans:
      MessageService:
        bean_type: "myapp.services.MessageService"
        implementation: "myapp.services.MockMessageService"
        scope: "singleton"

3. Initialize and Use

from bindry import ApplicationContext

# Initialize the context
context = ApplicationContext.get_instance()
context.load_configuration("application-context.yaml", active_profiles=["development"])

# Get and use components
notification_manager = context.get_bean(NotificationManager)
notification_manager.notify("Hello, World!")

🌍 Environment Variable Support

Bindry supports environment variable interpolation in configuration files:

profiles:
  default:
    beans:
      DatabaseService:
        bean_type: "myapp.services.DatabaseService"
        implementation: "myapp.services.DatabaseService"
        scope: "singleton"
        constructor_args:
          url: "${DATABASE_URL:sqlite:///default.db}"
          timeout: "${DB_TIMEOUT:30}"

πŸ”„ Profile Management

Using Multiple Profiles

context = ApplicationContext.get_instance()
context.set_active_profiles(["default", "development", "testing"])

Environment-Based Profiles

Set the ACTIVE_PROFILES environment variable:

export ACTIVE_PROFILES=development,testing

⚑ Advanced Features

Constructor Argument Injection

@component(
    scope=Scope.SINGLETON,
    bean_type=DatabaseService,
    constructor_args={
        "timeout": 30,
        "retries": 3,
        "kwargs": {"debug": True}
    }
)
class DatabaseService:
    def __init__(self, timeout: int, retries: int, **kwargs):
        self.timeout = timeout
        self.retries = retries
        self.debug = kwargs.get("debug", False)

Method Injection

@component(Scope.SINGLETON)
class ServiceManager:
    @autowired
    def configure(self, config_service: ConfigService):
        self.config_service = config_service

🀝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

πŸ“œ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™Œ Acknowledgments

This project was developed with the assistance of AI language models:

  • Initial implementation assistance provided by ChatGPT
  • Additional feature development and refinements by Claude.ai

While the code was primarily generated through AI assistance, all implementations have been carefully reviewed and tested to ensure quality and reliability.

❀️ Sponsor this project

Patreon

FAQs

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts