Skip to main content

Elegant Python Dependency Injection with Profile-Aware Configuration

Project description

🔗📚 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

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

bindry-0.1.4.tar.gz (57.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bindry-0.1.4-py3-none-any.whl (14.2 kB view details)

Uploaded Python 3

File details

Details for the file bindry-0.1.4.tar.gz.

File metadata

  • Download URL: bindry-0.1.4.tar.gz
  • Upload date:
  • Size: 57.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for bindry-0.1.4.tar.gz
Algorithm Hash digest
SHA256 7d5644082cfeca22ab11ea1b37b46119f7899a93fee01631c0eafe8116ed5416
MD5 1e7551797dd89aa9e1060c6e66c86b93
BLAKE2b-256 d12784a8631210db9f046fd8f86ed5763d61d481328cb49e83608344ac721906

See more details on using hashes here.

File details

Details for the file bindry-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: bindry-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 14.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for bindry-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 7ed54db9f880b18ca4aaa890b7500f2f20a154e16d66223d73c38d8cf3678aa1
MD5 18dc2542ad543511583f7d50147613d0
BLAKE2b-256 143ced4eb57266e5e25f738041a3244c917d6a24765ec0cdf382de922ce74ec9

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