{"id":10228,"library":"simple-di","title":"Simple-DI","description":"Simple-DI is a lightweight Python library for dependency injection. It helps manage application components and their dependencies in a clear, testable, and maintainable way using a container pattern. As of version 0.1.5, it provides core features like `Container` for organizing providers and `Provider` for defining how dependencies are created. Releases are infrequent, driven by new features or bug fixes.","status":"active","version":"0.1.5","language":"en","source_language":"en","source_url":"https://github.com/bentoml/simple_di","tags":["dependency-injection","di","container","framework-agnostic"],"install":[{"cmd":"pip install simple-di","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"Container","correct":"from simple_di import Container"},{"symbol":"Provider","correct":"from simple_di import Provider"}],"quickstart":{"code":"from simple_di import Container, Provider\n\nclass MyConfig(Container):\n    debug_mode = Provider(bool, default=False)\n    database_url = Provider(str, default=\"sqlite:///test.db\")\n\nclass MyDependencies(Container):\n    # Instantiate nested containers\n    config = MyConfig()\n\n    # A factory function for a database client\n    def _create_db_client(url: str):\n        print(f\"[DB] Connecting to {url}...\")\n        return f\"DatabaseClient({url})\"\n\n    # Define a provider for the database client, depending on config.database_url\n    db_client = Provider(_create_db_client, config.database_url)\n\n    # A factory function for the main application\n    def _create_app(client):\n        print(f\"[App] Creating app with client: {client}\")\n        return f\"MyApp({client})\"\n\n    # Define a provider for the app, depending on db_client\n    app = Provider(_create_app, db_client)\n\n# Instantiate the main dependency container\nmy_app_deps = MyDependencies()\n\n# Accessing dependencies (calling .get() is crucial to resolve them)\nprint(\"\\n--- First Resolution ---\")\ndb_client_instance = my_app_deps.db_client.get()\nprint(f\"Retrieved DB Client: {db_client_instance}\")\n\napp_instance = my_app_deps.app.get()\nprint(f\"Retrieved App: {app_instance}\")\n\n# Overriding a configuration value and observing changes\nprint(\"\\n--- Overriding Configuration ---\")\nmy_app_deps.config.database_url.set(\"postgresql://user:pass@host/prod_db\")\n\n# Accessing again will re-evaluate the db_client provider due to dependency change\nprint(\"\\n--- Second Resolution (after override) ---\")\nnew_db_client_instance = my_app_deps.db_client.get()\nprint(f\"Retrieved NEW DB Client: {new_db_client_instance}\")\n\n# Accessing app again will use the new db client\nnew_app_instance = my_app_deps.app.get()\nprint(f\"Retrieved NEW App: {new_app_instance}\")","lang":"python","description":"This quickstart demonstrates how to define a `Container` for configuration, nest containers, define `Provider` instances with dependencies, resolve dependencies using `.get()`, and dynamically override configuration values."},"warnings":[{"fix":"Change direct class access like `MyContainer.my_provider` to `MyContainer().my_provider` or, preferably, instantiate the container once: `my_container_instance = MyContainer()` and then use `my_container_instance.my_provider`.","message":"Prior to version 0.1.0, `Container` classes could be used directly to access providers (e.g., `MyContainer.my_provider`). From 0.1.0 onwards, `Container` classes must be instantiated (e.g., `my_container = MyContainer()`) before their providers can be accessed.","severity":"breaking","affected_versions":">=0.1.0"},{"fix":"Upgrade to `simple-di>=0.1.2` to ensure type hints are available for a better developer experience and more robust code.","message":"Versions prior to 0.1.2 did not ship with type information, potentially leading to issues with IDE auto-completion, static analysis, and type checkers like MyPy.","severity":"gotcha","affected_versions":"<0.1.2"},{"fix":"Change `my_deps.db_client` to `my_deps.db_client.get()` to retrieve the resolved dependency value.","message":"Accessing a `Provider` attribute directly (e.g., `my_deps.db_client`) returns the `Provider` object itself, not the resolved dependency. To obtain the actual value (the object that the provider is configured to create), you must call `.get()` on the provider.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Refactor your application's dependency graph to eliminate circular references. Ensure that dependencies always flow in a single, acyclic direction.","message":"Circular dependencies between `Provider` instances will lead to runtime errors (typically `RecursionError`) when the dependency graph is resolved. `simple-di` does not automatically detect or resolve these during setup.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-17T00:00:00.000Z","next_check":"2026-07-16T00:00:00.000Z","problems":[{"fix":"Instantiate the `Container` class: `my_instance = MyContainer()` and then access `my_instance.some_provider`.","cause":"Attempting to access a `Provider` attribute directly on a `Container` *class* after version 0.1.0, which requires the `Container` to be instantiated first.","error":"AttributeError: type object 'MyContainer' has no attribute 'some_provider'"},{"fix":"Verify that the dependency `some_dependency_name` is correctly defined as a `Provider` within your `Container` and that its name matches the injection request exactly.","cause":"A `Provider` attempts to inject a dependency that is not defined in the current or nested `Container` scope, or the name is misspelled.","error":"simple_di.errors.DependencyError: Provider 'some_dependency_name' not found in container"},{"fix":"Identify and break the circular dependency. Ensure providers are arranged in a Directed Acyclic Graph (DAG) where dependencies flow in one direction only.","cause":"Attempting to resolve a `Provider` that is part of a circular dependency chain, causing infinite recursion during resolution.","error":"RecursionError: maximum recursion depth exceeded while calling a Python object"}]}