Skip to content

proboscis/pinjected

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Pinjected Monorepo

codecov Python

Core Pinjected Framework

Welcome to Pinjected, a powerful dependency injection and dependency resolver library for Python inspired by pinject.

Prerequisites

  • Python 3.10 or higher
  • Basic understanding of Python decorators and functions

Installation

pip install pinjected

What is Dependency Injection?

Dependency injection is a design pattern where objects receive their dependencies from an external source rather than creating them internally. This makes code more:

  • Flexible: Easy to change implementations
  • Testable: Simple to mock dependencies
  • Maintainable: Clear separation of concerns

Core Concepts

  • @instance: Decorator that marks a function as a dependency provider
  • design(): Creates a design with dependencies (both value-based and function-based)
  • Design: Configuration registry that manages dependencies
  • to_graph(): Creates an object graph that resolves dependencies

Development

Please refer to Coding Guidelines for development standards and best practices.

This project uses uv for dependency management.

# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh

# Or install with pip
pip install uv

# Install dependencies
uv pip sync

日本語記事

Quick Start Guide

Basic Example

from pinjected import design, instance

# Define a simple configuration
@instance
def database_config():
    return {
        "host": "localhost",
        "port": 5432,
        "name": "mydb"
    }

@instance
def database_connection(database_config):
    # Dependencies are automatically injected
    return f"Connected to {database_config['name']} at {database_config['host']}:{database_config['port']}"

# Create a design with our configurations
di = design(
    db_config=database_config,
    connection=database_connection
)

# Use the dependency injection
graph = di.to_graph()
connection = graph['connection']
print(connection)  # "Connected to mydb at localhost:5432"

Common Use Cases

1. Configuration Management

from pinjected import design

# Base configuration
base_config = design(
    api_url="https://api.example.com",
    timeout=30
)

# Development overrides
dev_config = base_config + design(
    api_url="http://localhost:8000"
)

# Production overrides
prod_config = base_config + design(
    timeout=60
)

2. Service Dependencies

from pinjected import instance, design

@instance
def api_client(api_url, timeout):
    return f"Client configured with {api_url} (timeout: {timeout}s)"

@instance
def service(api_client):
    return f"Service using {api_client}"

# Create and use the service
di = dev_config + design(
    client=api_client,
    service=service
)
graph = di.to_graph()
my_service = graph['service']

3. Testing with Mock Dependencies

# Override dependencies for testing
test_config = design(
    api_url="mock://test",
    timeout=1
)

test_design = test_config + design(
    client=api_client,
    service=service
)

For more detailed documentation and advanced features, see:

Table of Contents

The documentation is organized into two directories:

Pinjected makes it easy to compose multiple Python objects to create a final object. It automatically creates dependencies and composes them, providing a clean and modular approach to dependency management. To learn more about the motivation behind Pinjected and its key concepts, check out the Introduction. Design

The Design section covers the core concept of Pinjected. It explains how to define a collection of objects and their dependencies using the Design class. You'll learn about binding instances, providers, and classes to create a dependency graph.

Pinjected provides two decorators, @instance and @injected, to define provider functions. The Decorators section explains the differences between these decorators and how to use them effectively in your code.

In the Injected section, you'll learn about the Injected class, which represents a variable that requires injection. This section covers how to create Injected instances, compose them, and use them as providers in your dependency graph.

Pinjected supports running Injected instances from the command line and integrating with IDEs like IntelliJ IDEA. The Running section provides details on how to use the CLI and set up IDE integration for a smooth development experience.

Pinjected offers support for asynchronous programming, allowing you to use async functions as providers. The Async Support section explains how to define and use async providers, as well as how to compose async Injected instances.

The Resolver section dives into the object graph and resolver concepts in Pinjected. You'll learn how the resolver manages the lifecycle of injected variables and how to use it to retrieve instances from the dependency graph.

For additional information, refer to the Miscellaneous section, which covers topics like performance considerations, comparisons with other DI libraries, and troubleshooting.

The Appendix contains supplementary information, such as a comparison with pinject and other relevant details.

Stay up to date with the latest changes and releases by checking the Updates section, which includes a changelog and release information.

The Migration Guides section provides step-by-step instructions for transitioning from deprecated APIs to newer ones. Currently featuring a comprehensive guide for migrating from instances(), providers(), and classes() to the new unified design() function.

We hope you find Pinjected helpful in your projects! If you have any questions or feedback, please don't hesitate to reach out.

Pinjected Monorepo Structure

This repository is organized as a monorepo with the following packages:

  • pinjected: Core dependency injection framework (root package)
  • pinjected-openai: OpenAI API bindings for pinjected (in packages/openai_support)
  • pinjected-anthropic: Anthropic API bindings for pinjected (in packages/anthropic)
  • pinjected-wandb: Weights & Biases integration for pinjected (in packages/wandb_util)
  • pinjected-error-reports: Error reporting utilities for pinjected (in packages/error_reports)
  • pinjected-reviewer: Code review tools for pinjected (in packages/reviewer)
  • pinjected-rate-limit: Rate limiting utilities for API calls (in packages/rate_limit)
  • pinjected-niji-voice: Niji Voice integration for pinjected (in packages/niji_voice)
  • injected-utils: Utility functions for pinjected packages (in packages/injected_utils)

Working with the Monorepo

System Dependencies

The pinjected linter requires system dependencies for Rust compilation. These are automatically installed when you run make sync, but you can also install them manually:

Ubuntu/Debian

sudo apt-get update
sudo apt-get install -y pkg-config libssl-dev

RHEL/CentOS/Fedora

sudo yum install -y pkg-config openssl-devel

macOS

brew install pkg-config openssl

If you encounter linter compilation errors, try running:

make install-system-deps

Installation

To install all packages for development:

# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh

# Set up the workspace
make sync
make setup-all

Running Tests

Run tests for all packages:

make test

Building Packages

Build individual packages:

make publish          # Build and publish pinjected
make publish-openai   # Build and publish pinjected-openai
# And other packages similarly

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •