diff --git a/docs/examples/bundles_miniapp.rst b/docs/examples/bundles_miniapp.rst
new file mode 100644
index 00000000..df7a4511
--- /dev/null
+++ b/docs/examples/bundles_miniapp.rst
@@ -0,0 +1,77 @@
+Bundles mini application example
+--------------------------------
+
+.. currentmodule:: dependency_injector.containers
+
+"Bundles" is an example mini application that is intented to demonstrate the
+power of dependency injection for creation of re-usable application components
+("bundles") with 100% transparency of their dependencies.
+
+Example application
+~~~~~~~~~~~~~~~~~~~
+
+"Bundles" mini application has next structure:
+
+.. code-block:: bash
+
+ bundles/
+ bundles/ <-- Bundles package
+ photos/ <-- Photos bundle
+ __init__.py <-- Photos bundle dependency injection container
+ entities.py
+ repositories.py
+ users/ <-- Users bundle
+ __init__.py <-- Users bundle dependency injection container
+ entities.py
+ repositories.py
+ run.py <-- Entrypoint
+
+
+IoC containers
+~~~~~~~~~~~~~~
+
+Next two listings show :py:class:`DeclarativeContainer`'s for "users" and
+"photos" bundles.
+
+Listing of ``bundeles/users/__init__.py``:
+
+.. literalinclude:: ../../examples/miniapps/bundles/bundles/users/__init__.py
+ :language: python
+ :linenos:
+
+.. note::
+
+ - ``Users`` container has dependency on database.
+
+Listing of ``bundeles/photos/__init__.py``:
+
+.. literalinclude:: ../../examples/miniapps/bundles/bundles/photos/__init__.py
+ :language: python
+ :linenos:
+
+.. note::
+
+ - ``Photos`` container has dependencies on database and file storage.
+
+Run application
+~~~~~~~~~~~~~~~
+
+Finally, both "bundles" are initialized by providing needed dependencies.
+Initialization of dependencies happens right in the runtime, not earlier.
+Generally, it means, that any part of any bundle could be overridden on the
+fly.
+
+Listing of ``run.py``:
+
+.. literalinclude:: ../../examples/miniapps/bundles/run.py
+ :language: python
+ :linenos:
+
+Links
+~~~~~
+
++ `Dependency Injector `_
++ `Full example sources `_
+
+
+.. disqus::
diff --git a/docs/examples/index.rst b/docs/examples/index.rst
index 3d57076e..230bf2ef 100644
--- a/docs/examples/index.rst
+++ b/docs/examples/index.rst
@@ -17,3 +17,4 @@ and powered by *Dependency Injector* framework.
movie_lister
services_miniapp
+ bundles_miniapp
diff --git a/docs/main/changelog.rst b/docs/main/changelog.rst
index c7ab32c5..dd7ec154 100644
--- a/docs/main/changelog.rst
+++ b/docs/main/changelog.rst
@@ -20,6 +20,7 @@ Development version
- Add method to dynamic catalog for overriding groups of providers -
``DynamicContainer.set_providers(**overriding_providers)``.
- Fix bug when copying ``Configuration`` provider.
+- Add "bundles" example miniapp.
3.8.2
diff --git a/examples/miniapps/bundles/run.py b/examples/miniapps/bundles/run.py
index b5da7baf..00f8ae0e 100644
--- a/examples/miniapps/bundles/run.py
+++ b/examples/miniapps/bundles/run.py
@@ -1,4 +1,7 @@
-"""Example application - Bundles."""
+"""Run 'Bundles' example application."""
+
+import sqlite3
+import boto3
from dependency_injector import containers
from dependency_injector import providers
@@ -10,15 +13,22 @@ from bundles.photos import Photos
class Core(containers.DeclarativeContainer):
"""Core container."""
- pgsql = providers.Singleton(object)
- s3 = providers.Singleton(object)
+ config = providers.Configuration('config')
+ sqlite = providers.Singleton(sqlite3.connect, config.database.dsn)
+ s3 = providers.Singleton(
+ boto3.client, 's3',
+ aws_access_key_id=config.aws.access_key_id,
+ aws_secret_access_key=config.aws.secret_access_key)
if __name__ == '__main__':
# Initializing containers
core = Core()
- users = Users(database=core.pgsql)
- photos = Photos(database=core.pgsql, file_storage=core.s3)
+ core.config.update({'database': {'dsn': ':memory:'},
+ 'aws': {'access_key_id': 'KEY',
+ 'secret_access_key': 'SECRET'}})
+ users = Users(database=core.sqlite)
+ photos = Photos(database=core.sqlite, file_storage=core.s3)
# Fetching few users
user_repository = users.user_repository()
@@ -28,4 +38,4 @@ if __name__ == '__main__':
# Making some checks
assert user1.id == 1
assert user2.id == 2
- assert user_repository.db is core.pgsql()
+ assert user_repository.db is core.sqlite()