mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-03-03 19:25:48 +03:00
Merge pull request #136 from ets-labs/deprecate_inject_decorator
Deprecate inject decorator
This commit is contained in:
commit
53f60d6fed
73
README.rst
73
README.rst
|
@ -62,6 +62,8 @@ system that consists from several business and platform services:
|
|||
|
||||
import sqlite3
|
||||
import boto.s3.connection
|
||||
|
||||
import example.main
|
||||
import example.services
|
||||
|
||||
import dependency_injector.containers as containers
|
||||
|
@ -92,29 +94,38 @@ system that consists from several business and platform services:
|
|||
db=Platform.database,
|
||||
s3=Platform.s3)
|
||||
|
||||
Next example demonstrates usage of ``@inject`` decorator with IoC containers
|
||||
defined above:
|
||||
|
||||
class Application(containers.DeclarativeContainer):
|
||||
"""IoC container of application component providers."""
|
||||
|
||||
main = providers.Callable(example.main.main,
|
||||
users_service=Services.users,
|
||||
auth_service=Services.auth,
|
||||
photos_service=Services.photos)
|
||||
|
||||
Next example demonstrates usage of IoC containers & providers defined above:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
"""Dependency Injector @inject decorator example."""
|
||||
"""Run example application."""
|
||||
|
||||
import application
|
||||
import dependency_injector.injections as injections
|
||||
|
||||
|
||||
@injections.inject(users_service=application.Services.users)
|
||||
@injections.inject(auth_service=application.Services.auth)
|
||||
@injections.inject(photos_service=application.Services.photos)
|
||||
def main(users_service, auth_service, photos_service):
|
||||
"""Main function."""
|
||||
user = users_service.get_user('user')
|
||||
auth_service.authenticate(user, 'secret')
|
||||
photos_service.upload_photo(user['id'], 'photo.jpg')
|
||||
import containers
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
containers.Application.main()
|
||||
|
||||
# Previous call is an equivalent of next operations:
|
||||
#
|
||||
# database = sqlite3.connect(':memory:')
|
||||
# s3 = boto.s3.connection.S3Connection(aws_access_key_id='KEY',
|
||||
# aws_secret_access_key='SECRET')
|
||||
#
|
||||
# example.main.main(users_service=example.services.Users(db=database),
|
||||
# auth_service=example.services.Auth(db=database,
|
||||
# token_ttl=3600),
|
||||
# photos_service=example.services.Photos(db=database,
|
||||
# s3=s3))
|
||||
|
||||
Alternative definition styles
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -136,21 +147,6 @@ IoC containers from previous example could look like these:
|
|||
.add_kwargs(aws_access_key_id='KEY',
|
||||
aws_secret_access_key='SECRET')
|
||||
|
||||
|
||||
class Services(containers.DeclarativeContainer):
|
||||
"""IoC container of business service providers."""
|
||||
|
||||
users = providers.Factory(example.services.Users) \
|
||||
.add_kwargs(db=Platform.database)
|
||||
|
||||
auth = providers.Factory(example.services.Auth) \
|
||||
.add_kwargs(db=Platform.database,
|
||||
token_ttl=3600)
|
||||
|
||||
photos = providers.Factory(example.services.Photos) \
|
||||
.add_kwargs(db=Platform.database,
|
||||
s3=Platform.s3)
|
||||
|
||||
or like this these:
|
||||
|
||||
.. code-block:: python
|
||||
|
@ -165,21 +161,6 @@ or like this these:
|
|||
s3.add_kwargs(aws_access_key_id='KEY',
|
||||
aws_secret_access_key='SECRET')
|
||||
|
||||
|
||||
class Services(containers.DeclarativeContainer):
|
||||
"""IoC container of business service providers."""
|
||||
|
||||
users = providers.Factory(example.services.Users)
|
||||
users.add_kwargs(db=Platform.database)
|
||||
|
||||
auth = providers.Factory(example.services.Auth)
|
||||
auth.add_kwargs(db=Platform.database,
|
||||
token_ttl=3600)
|
||||
|
||||
photos = providers.Factory(example.services.Photos)
|
||||
photos.add_kwargs(db=Platform.database,
|
||||
s3=Platform.s3)
|
||||
|
||||
You can get more *Dependency Injector* examples in ``/examples`` directory on
|
||||
GitHub:
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
"""Dependency injector injections module."""
|
||||
|
||||
import warnings
|
||||
|
||||
import six
|
||||
|
||||
from dependency_injector.providers.base import (
|
||||
|
@ -13,6 +15,13 @@ from dependency_injector import errors
|
|||
def inject(*args, **kwargs):
|
||||
"""Dependency injection decorator.
|
||||
|
||||
.. warning::
|
||||
|
||||
:py:func:`inject` decorator has been deprecated since version 2.2.0.
|
||||
|
||||
Usage of :py:func:`inject` decorator can lead to bad design and could
|
||||
be considered as anti-pattern.
|
||||
|
||||
:py:func:`inject` decorator can be used for making inline dependency
|
||||
injections. It patches decorated callable in such way that dependency
|
||||
injection will be done during every call of decorated callable.
|
||||
|
@ -41,6 +50,10 @@ def inject(*args, **kwargs):
|
|||
def __init__(self, arg1, arg2):
|
||||
pass
|
||||
|
||||
.. deprecated:: 2.2.0
|
||||
Usage of :py:func:`inject` decorator can lead to bad design and could
|
||||
be considered as anti-pattern.
|
||||
|
||||
:param args: Tuple of context positional arguments.
|
||||
:type args: tuple[object]
|
||||
|
||||
|
@ -50,6 +63,11 @@ def inject(*args, **kwargs):
|
|||
:return: Class / callable decorator
|
||||
:rtype: (callable) -> (type | callable)
|
||||
"""
|
||||
warnings.warn(message='Call to a deprecated decorator - @{0}.{1}'
|
||||
.format(inject.__module__, inject.__name__),
|
||||
category=DeprecationWarning,
|
||||
stacklevel=2)
|
||||
|
||||
arg_injections = _parse_positional_injections(args)
|
||||
kwarg_injections = _parse_keyword_injections(kwargs)
|
||||
|
||||
|
|
|
@ -9,6 +9,10 @@ Current section of documentation describes advanced usage of
|
|||
|
||||
.. currentmodule:: dependency_injector.injections
|
||||
|
||||
.. warning::
|
||||
|
||||
:py:func:`inject` decorator has been deprecated since version 2.2.0.
|
||||
|
||||
:py:func:`inject` decorator is a part of
|
||||
:py:mod:`dependency_injector.injections` module.
|
||||
|
||||
|
|
|
@ -7,6 +7,5 @@ API Documentation
|
|||
top_level
|
||||
providers
|
||||
containers
|
||||
injections
|
||||
utils
|
||||
errors
|
||||
|
|
|
@ -9,8 +9,8 @@ Examples
|
|||
"Dependency Injector" framework.
|
||||
|
||||
Current section of documentation is designed to provide several example mini
|
||||
applications that are built on the top of inversion of control principle and
|
||||
powered by *Dependency Injector* framework.
|
||||
applications that are built according to the inversion of control principle
|
||||
and powered by *Dependency Injector* framework.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
|
|
@ -20,14 +20,14 @@ Like Martin says:
|
|||
|
||||
While original Martin's MovieLister example was a bit modified here, it
|
||||
makes sense to provide some description. So, the idea of this example is to
|
||||
create ``movies`` library that can be configurable to work with different
|
||||
movie databases (csv, sqlite) and provide 2 main features:
|
||||
create ``movies`` library that can be configured to work with different
|
||||
movie databases (csv, sqlite, etc...) and provide 2 main features:
|
||||
|
||||
1. List all movies that were directed by certain person.
|
||||
2. List all movies that were released in certain year.
|
||||
|
||||
Also this example contains 3 mini applications that are based on ``movies``
|
||||
library :
|
||||
library:
|
||||
|
||||
1. ``app_csv.py`` - list movies by certain criteria from csv file database.
|
||||
2. ``app_db.py`` - list movies by certain criteria from sqlite database.
|
||||
|
@ -38,8 +38,6 @@ Instructions for running:
|
|||
|
||||
.. code-block:: bash
|
||||
|
||||
python create_db.py
|
||||
|
||||
python app_csv.py
|
||||
python app_db.py
|
||||
python app_db_csv.py
|
||||
|
@ -74,6 +72,30 @@ Listing of ``movies/__init__.py``:
|
|||
:language: python
|
||||
:linenos:
|
||||
|
||||
Example application
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Example application structure:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
/example
|
||||
/__init__.py
|
||||
/db.py
|
||||
/main.py
|
||||
|
||||
Listing of ``examples/main.py``:
|
||||
|
||||
.. literalinclude:: ../../examples/miniapps/movie_lister/example/main.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
Listing of ``examples/db.py``:
|
||||
|
||||
.. literalinclude:: ../../examples/miniapps/movie_lister/example/db.py
|
||||
:language: python
|
||||
:linenos:
|
||||
|
||||
Csv application
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -59,7 +59,6 @@ Contents
|
|||
main/installation
|
||||
providers/index
|
||||
containers/index
|
||||
advanced_usage/index
|
||||
examples/index
|
||||
api/index
|
||||
main/feedback
|
||||
|
|
|
@ -9,7 +9,7 @@ follows `Semantic versioning`_
|
|||
|
||||
Development version
|
||||
-------------------
|
||||
- No features.
|
||||
- Deprecate ``inject`` decorator.
|
||||
|
||||
2.1.1
|
||||
-----
|
||||
|
|
|
@ -11,8 +11,6 @@ Instructions for running:
|
|||
|
||||
.. code-block:: bash
|
||||
|
||||
python create_db.py
|
||||
|
||||
python app_csv.py
|
||||
python app_db.py
|
||||
python app_db_csv.py
|
||||
|
|
|
@ -9,42 +9,40 @@ This mini application uses ``movies`` library, that is configured to work with
|
|||
csv file movies database.
|
||||
"""
|
||||
|
||||
import dependency_injector.containers as containers
|
||||
import dependency_injector.providers as providers
|
||||
import dependency_injector.injections as injections
|
||||
|
||||
import movies
|
||||
import movies.finders
|
||||
|
||||
import example.db
|
||||
import example.main
|
||||
|
||||
import settings
|
||||
|
||||
import dependency_injector.containers as containers
|
||||
import dependency_injector.providers as providers
|
||||
|
||||
|
||||
@containers.override(movies.MoviesModule)
|
||||
class MyMoviesModule(containers.DeclarativeContainer):
|
||||
"""IoC container for overriding movies module component providers."""
|
||||
|
||||
movie_finder = providers.Factory(movies.finders.CsvMovieFinder,
|
||||
csv_file=settings.MOVIES_CSV_PATH,
|
||||
delimeter=',',
|
||||
csv_file_path=settings.MOVIES_CSV_PATH,
|
||||
delimiter=',',
|
||||
**movies.MoviesModule.movie_finder.kwargs)
|
||||
|
||||
|
||||
@injections.inject(movies.MoviesModule.movie_lister)
|
||||
def main(movie_lister):
|
||||
"""Main function.
|
||||
class CsvApplication(containers.DeclarativeContainer):
|
||||
"""IoC container of csv application component providers."""
|
||||
|
||||
This program prints info about all movies that were directed by different
|
||||
persons and then prints all movies that were released in 2015.
|
||||
main = providers.Callable(example.main.main,
|
||||
movie_lister=movies.MoviesModule.movie_lister)
|
||||
|
||||
:param movie_lister: Movie lister instance
|
||||
:type movie_lister: movies.listers.MovieLister
|
||||
"""
|
||||
print movie_lister.movies_directed_by('Francis Lawrence')
|
||||
print movie_lister.movies_directed_by('Patricia Riggen')
|
||||
print movie_lister.movies_directed_by('JJ Abrams')
|
||||
|
||||
print movie_lister.movies_released_in(2015)
|
||||
init_db = providers.Callable(example.db.init_csv,
|
||||
movies_data=settings.MOVIES_SAMPLE_DATA,
|
||||
csv_file_path=settings.MOVIES_CSV_PATH,
|
||||
delimiter=',')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
CsvApplication.init_db()
|
||||
CsvApplication.main()
|
||||
|
|
|
@ -11,18 +11,20 @@ sqlite movies database.
|
|||
|
||||
import sqlite3
|
||||
|
||||
import dependency_injector.containers as containers
|
||||
import dependency_injector.providers as providers
|
||||
import dependency_injector.injections as injections
|
||||
|
||||
import movies
|
||||
import movies.finders
|
||||
|
||||
import example.db
|
||||
import example.main
|
||||
|
||||
import settings
|
||||
|
||||
import dependency_injector.containers as containers
|
||||
import dependency_injector.providers as providers
|
||||
|
||||
class ApplicationModule(containers.DeclarativeContainer):
|
||||
"""IoC container of application component providers."""
|
||||
|
||||
class ResourcesModule(containers.DeclarativeContainer):
|
||||
"""IoC container of application resource providers."""
|
||||
|
||||
database = providers.Singleton(sqlite3.connect, settings.MOVIES_DB_PATH)
|
||||
|
||||
|
@ -32,26 +34,21 @@ class MyMoviesModule(containers.DeclarativeContainer):
|
|||
"""IoC container for overriding movies module component providers."""
|
||||
|
||||
movie_finder = providers.Factory(movies.finders.SqliteMovieFinder,
|
||||
database=ApplicationModule.database,
|
||||
database=ResourcesModule.database,
|
||||
**movies.MoviesModule.movie_finder.kwargs)
|
||||
|
||||
|
||||
@injections.inject(movies.MoviesModule.movie_lister)
|
||||
def main(movie_lister):
|
||||
"""Main function.
|
||||
class DbApplication(containers.DeclarativeContainer):
|
||||
"""IoC container of database application component providers."""
|
||||
|
||||
This program prints info about all movies that were directed by different
|
||||
persons and then prints all movies that were released in 2015.
|
||||
main = providers.Callable(example.main.main,
|
||||
movie_lister=movies.MoviesModule.movie_lister)
|
||||
|
||||
:param movie_lister: Movie lister instance
|
||||
:type movie_lister: movies.listers.MovieLister
|
||||
"""
|
||||
print movie_lister.movies_directed_by('Francis Lawrence')
|
||||
print movie_lister.movies_directed_by('Patricia Riggen')
|
||||
print movie_lister.movies_directed_by('JJ Abrams')
|
||||
|
||||
print movie_lister.movies_released_in(2015)
|
||||
init_db = providers.Callable(example.db.init_sqlite,
|
||||
movies_data=settings.MOVIES_SAMPLE_DATA,
|
||||
database=ResourcesModule.database)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
DbApplication.init_db()
|
||||
DbApplication.main()
|
||||
|
|
|
@ -11,18 +11,20 @@ sqlite movies database and csv file movies database.
|
|||
|
||||
import sqlite3
|
||||
|
||||
import dependency_injector.containers as containers
|
||||
import dependency_injector.providers as providers
|
||||
import dependency_injector.injections as injections
|
||||
|
||||
import movies
|
||||
import movies.finders
|
||||
|
||||
import example.db
|
||||
import example.main
|
||||
|
||||
import settings
|
||||
|
||||
import dependency_injector.containers as containers
|
||||
import dependency_injector.providers as providers
|
||||
|
||||
class ApplicationModule(containers.DeclarativeContainer):
|
||||
"""IoC container of application component providers."""
|
||||
|
||||
class ResourcesModule(containers.DeclarativeContainer):
|
||||
"""IoC container of application resource providers."""
|
||||
|
||||
database = providers.Singleton(sqlite3.connect, settings.MOVIES_DB_PATH)
|
||||
|
||||
|
@ -32,7 +34,7 @@ class DbMoviesModule(movies.MoviesModule):
|
|||
"""IoC container for overriding movies module component providers."""
|
||||
|
||||
movie_finder = providers.Factory(movies.finders.SqliteMovieFinder,
|
||||
database=ApplicationModule.database,
|
||||
database=ResourcesModule.database,
|
||||
**movies.MoviesModule.movie_finder.kwargs)
|
||||
|
||||
|
||||
|
@ -41,31 +43,36 @@ class CsvMoviesModule(movies.MoviesModule):
|
|||
"""IoC container for overriding movies module component providers."""
|
||||
|
||||
movie_finder = providers.Factory(movies.finders.CsvMovieFinder,
|
||||
csv_file=settings.MOVIES_CSV_PATH,
|
||||
delimeter=',',
|
||||
csv_file_path=settings.MOVIES_CSV_PATH,
|
||||
delimiter=',',
|
||||
**movies.MoviesModule.movie_finder.kwargs)
|
||||
|
||||
|
||||
@injections.inject(db_movie_lister=DbMoviesModule.movie_lister)
|
||||
@injections.inject(csv_movie_lister=CsvMoviesModule.movie_lister)
|
||||
def main(db_movie_lister, csv_movie_lister):
|
||||
"""Main function.
|
||||
class DbApplication(containers.DeclarativeContainer):
|
||||
"""IoC container of database application component providers."""
|
||||
|
||||
This program prints info about all movies that were directed by different
|
||||
persons and then prints all movies that were released in 2015.
|
||||
main = providers.Callable(example.main.main,
|
||||
movie_lister=DbMoviesModule.movie_lister)
|
||||
|
||||
:param db_movie_lister: Movie lister, configured to work with database
|
||||
:type db_movie_lister: movies.listers.MovieLister
|
||||
init_db = providers.Callable(example.db.init_sqlite,
|
||||
movies_data=settings.MOVIES_SAMPLE_DATA,
|
||||
database=ResourcesModule.database)
|
||||
|
||||
:param csv_movie_lister: Movie lister, configured to work with csv file
|
||||
:type csv_movie_lister: movies.listers.MovieLister
|
||||
"""
|
||||
for movie_lister in (db_movie_lister, csv_movie_lister):
|
||||
print movie_lister.movies_directed_by('Francis Lawrence')
|
||||
print movie_lister.movies_directed_by('Patricia Riggen')
|
||||
print movie_lister.movies_directed_by('JJ Abrams')
|
||||
print movie_lister.movies_released_in(2015)
|
||||
|
||||
class CsvApplication(containers.DeclarativeContainer):
|
||||
"""IoC container of csv application component providers."""
|
||||
|
||||
main = providers.Callable(example.main.main,
|
||||
movie_lister=CsvMoviesModule.movie_lister)
|
||||
|
||||
init_db = providers.Callable(example.db.init_csv,
|
||||
movies_data=settings.MOVIES_SAMPLE_DATA,
|
||||
csv_file_path=settings.MOVIES_CSV_PATH,
|
||||
delimiter=',')
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
DbApplication.init_db()
|
||||
DbApplication.main()
|
||||
|
||||
CsvApplication.init_db()
|
||||
CsvApplication.main()
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
"""Script for initializing movie databases."""
|
||||
|
||||
import os
|
||||
import csv
|
||||
import sqlite3
|
||||
import shutil
|
||||
|
||||
from settings import DATA_DIR
|
||||
from settings import MOVIES_CSV_PATH
|
||||
from settings import MOVIES_DB_PATH
|
||||
|
||||
|
||||
MOVIES = (('The Hunger Games: Mockingjay - Part 2', 2015, 'Francis Lawrence'),
|
||||
('The 33', 2015, 'Patricia Riggen'),
|
||||
('Star Wars: Episode VII - The Force Awakens', 2015, 'JJ Abrams'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# (Re)create data directory:
|
||||
if os.path.exists(DATA_DIR):
|
||||
shutil.rmtree(DATA_DIR)
|
||||
os.makedirs(DATA_DIR)
|
||||
|
||||
# Initialize sqlite database:
|
||||
connection = sqlite3.connect(MOVIES_DB_PATH)
|
||||
with connection:
|
||||
connection.execute('CREATE TABLE movies '
|
||||
'(name text, year int, director text)')
|
||||
connection.executemany('INSERT INTO movies VALUES (?,?,?)', MOVIES)
|
||||
|
||||
# Initialize csv database:
|
||||
with open(MOVIES_CSV_PATH, 'w') as csv_file:
|
||||
csv.writer(csv_file).writerows(MOVIES)
|
5
examples/miniapps/movie_lister/data/.gitignore
vendored
Normal file
5
examples/miniapps/movie_lister/data/.gitignore
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
# Ignore everything in this directory
|
||||
*
|
||||
|
||||
# Except this file:
|
||||
!.gitignore
|
1
examples/miniapps/movie_lister/example/__init__.py
Normal file
1
examples/miniapps/movie_lister/example/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
"""Example top-level package."""
|
35
examples/miniapps/movie_lister/example/db.py
Normal file
35
examples/miniapps/movie_lister/example/db.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
"""Example database module."""
|
||||
|
||||
import csv
|
||||
|
||||
|
||||
def init_sqlite(movies_data, database):
|
||||
"""Initialize sqlite3 movies database.
|
||||
|
||||
:param movies_data: Data about movies
|
||||
:type movies_data: tuple[tuple]
|
||||
|
||||
:param database: Connection to sqlite database with movies data
|
||||
:type database: sqlite3.Connection
|
||||
"""
|
||||
with database:
|
||||
database.execute('CREATE TABLE IF NOT EXISTS movies '
|
||||
'(name text, year int, director text)')
|
||||
database.execute('DELETE FROM movies')
|
||||
database.executemany('INSERT INTO movies VALUES (?,?,?)', movies_data)
|
||||
|
||||
|
||||
def init_csv(movies_data, csv_file_path, delimiter):
|
||||
"""Initialize csv movies database.
|
||||
|
||||
:param movies_data: Data about movies
|
||||
:type movies_data: tuple[tuple]
|
||||
|
||||
:param csv_file_path: Path to csv file with movies data
|
||||
:type csv_file_path: str
|
||||
|
||||
:param delimiter: Csv file's delimiter
|
||||
:type delimiter: str
|
||||
"""
|
||||
with open(csv_file_path, 'w') as csv_file:
|
||||
csv.writer(csv_file, delimiter=delimiter).writerows(movies_data)
|
17
examples/miniapps/movie_lister/example/main.py
Normal file
17
examples/miniapps/movie_lister/example/main.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
"""Example main module."""
|
||||
|
||||
|
||||
def main(movie_lister):
|
||||
"""Main function.
|
||||
|
||||
This program prints info about all movies that were directed by different
|
||||
persons and then prints all movies that were released in 2015.
|
||||
|
||||
:param movie_lister: Movie lister instance
|
||||
:type movie_lister: movies.listers.MovieLister
|
||||
"""
|
||||
print(movie_lister.movies_directed_by('Francis Lawrence'))
|
||||
print(movie_lister.movies_directed_by('Patricia Riggen'))
|
||||
print(movie_lister.movies_directed_by('JJ Abrams'))
|
||||
|
||||
print(movie_lister.movies_released_in(2015))
|
|
@ -12,13 +12,13 @@ concrete finder implementation in terms of library configuration.
|
|||
Each of ``MoviesModule`` providers could be overridden.
|
||||
"""
|
||||
|
||||
import dependency_injector.containers as containers
|
||||
import dependency_injector.providers as providers
|
||||
|
||||
import movies.finders
|
||||
import movies.listers
|
||||
import movies.models
|
||||
|
||||
import dependency_injector.containers as containers
|
||||
import dependency_injector.providers as providers
|
||||
|
||||
|
||||
class MoviesModule(containers.DeclarativeContainer):
|
||||
"""IoC container of movies module component providers."""
|
||||
|
|
|
@ -33,20 +33,20 @@ class MovieFinder(object):
|
|||
class CsvMovieFinder(MovieFinder):
|
||||
"""Movie finder that fetches movies data from csv file."""
|
||||
|
||||
def __init__(self, movie_model, csv_file, delimeter):
|
||||
def __init__(self, movie_model, csv_file_path, delimiter):
|
||||
"""Initializer.
|
||||
|
||||
:param movie_model: Movie model's factory
|
||||
:type movie_model: movies.models.Movie
|
||||
|
||||
:param csv_file: Path to csv file with movies data
|
||||
:type csv_file: str
|
||||
:param csv_file_path: Path to csv file with movies data
|
||||
:type csv_file_path: str
|
||||
|
||||
:param delimeter: Csv file's delimeter
|
||||
:type delimeter: str
|
||||
:param delimiter: Csv file's delimiter
|
||||
:type delimiter: str
|
||||
"""
|
||||
self._csv_file = csv_file
|
||||
self._delimeter = delimeter
|
||||
self._csv_file_path = csv_file_path
|
||||
self._delimiter = delimiter
|
||||
super(CsvMovieFinder, self).__init__(movie_model)
|
||||
|
||||
def find_all(self):
|
||||
|
@ -55,9 +55,9 @@ class CsvMovieFinder(MovieFinder):
|
|||
:rtype: list[movies.models.Movie]
|
||||
:return: List of movie instances.
|
||||
"""
|
||||
with open(self._csv_file) as csv_file:
|
||||
reader = csv.reader(csv_file, delimiter=self._delimeter)
|
||||
return [self._movie_model(*row) for row in reader]
|
||||
with open(self._csv_file_path) as csv_file:
|
||||
csv_reader = csv.reader(csv_file, delimiter=self._delimiter)
|
||||
return [self._movie_model(*row) for row in csv_reader]
|
||||
|
||||
|
||||
class SqliteMovieFinder(MovieFinder):
|
||||
|
|
|
@ -7,8 +7,11 @@ import os
|
|||
|
||||
|
||||
DATA_DIR = os.path.abspath(os.path.dirname(__file__) + '/data')
|
||||
|
||||
MOVIES_CSV_PATH = DATA_DIR + '/movies.csv'
|
||||
MOVIES_CSV_DELIMETER = ','
|
||||
|
||||
MOVIES_DB_PATH = DATA_DIR + '/movies.db'
|
||||
|
||||
MOVIES_SAMPLE_DATA = (
|
||||
('The Hunger Games: Mockingjay - Part 2', 2015, 'Francis Lawrence'),
|
||||
('The 33', 2015, 'Patricia Riggen'),
|
||||
('Star Wars: Episode VII - The Force Awakens', 2015, 'JJ Abrams'),
|
||||
)
|
||||
|
|
|
@ -5,4 +5,4 @@ Instructions for running
|
|||
|
||||
.. code-block:: bash
|
||||
|
||||
python main.py
|
||||
python run.py
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
import sqlite3
|
||||
import boto.s3.connection
|
||||
|
||||
import example.main
|
||||
import example.services
|
||||
|
||||
import dependency_injector.containers as containers
|
||||
|
@ -31,3 +33,12 @@ class Services(containers.DeclarativeContainer):
|
|||
photos = providers.Factory(example.services.Photos,
|
||||
db=Platform.database,
|
||||
s3=Platform.s3)
|
||||
|
||||
|
||||
class Application(containers.DeclarativeContainer):
|
||||
"""IoC container of application component providers."""
|
||||
|
||||
main = providers.Callable(example.main.main,
|
||||
users_service=Services.users,
|
||||
auth_service=Services.auth,
|
||||
photos_service=Services.photos)
|
|
@ -5,6 +5,8 @@ Alternative injections definition style #1.
|
|||
|
||||
import sqlite3
|
||||
import boto.s3.connection
|
||||
|
||||
import example.main
|
||||
import example.services
|
||||
|
||||
import dependency_injector.containers as containers
|
||||
|
@ -35,3 +37,12 @@ class Services(containers.DeclarativeContainer):
|
|||
photos = providers.Factory(example.services.Photos) \
|
||||
.add_kwargs(db=Platform.database,
|
||||
s3=Platform.s3)
|
||||
|
||||
|
||||
class Application(containers.DeclarativeContainer):
|
||||
"""IoC container of application component providers."""
|
||||
|
||||
main = providers.Callable(example.main.main) \
|
||||
.add_kwargs(users_service=Services.users,
|
||||
auth_service=Services.auth,
|
||||
photos_service=Services.photos)
|
|
@ -5,6 +5,8 @@ Alternative injections definition style #2.
|
|||
|
||||
import sqlite3
|
||||
import boto.s3.connection
|
||||
|
||||
import example.main
|
||||
import example.services
|
||||
|
||||
import dependency_injector.containers as containers
|
||||
|
@ -35,3 +37,12 @@ class Services(containers.DeclarativeContainer):
|
|||
photos = providers.Factory(example.services.Photos)
|
||||
photos.add_kwargs(db=Platform.database,
|
||||
s3=Platform.s3)
|
||||
|
||||
|
||||
class Application(containers.DeclarativeContainer):
|
||||
"""IoC container of application component providers."""
|
||||
|
||||
main = providers.Callable(example.main.main)
|
||||
main.add_kwargs(users_service=Services.users,
|
||||
auth_service=Services.auth,
|
||||
photos_service=Services.photos)
|
8
examples/miniapps/services/example/main.py
Normal file
8
examples/miniapps/services/example/main.py
Normal file
|
@ -0,0 +1,8 @@
|
|||
"""Example main module."""
|
||||
|
||||
|
||||
def main(users_service, auth_service, photos_service):
|
||||
"""Example main function."""
|
||||
user = users_service.get_user('user')
|
||||
auth_service.authenticate(user, 'secret')
|
||||
photos_service.upload_photo(user['id'], 'photo.jpg')
|
|
@ -1,18 +0,0 @@
|
|||
"""Dependency Injector @inject decorator example."""
|
||||
|
||||
import application
|
||||
import dependency_injector.injections as injections
|
||||
|
||||
|
||||
@injections.inject(users_service=application.Services.users)
|
||||
@injections.inject(auth_service=application.Services.auth)
|
||||
@injections.inject(photos_service=application.Services.photos)
|
||||
def main(users_service, auth_service, photos_service):
|
||||
"""Main function."""
|
||||
user = users_service.get_user('user')
|
||||
auth_service.authenticate(user, 'secret')
|
||||
photos_service.upload_photo(user['id'], 'photo.jpg')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
19
examples/miniapps/services/run.py
Normal file
19
examples/miniapps/services/run.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
"""Run example application."""
|
||||
|
||||
import containers
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
containers.Application.main()
|
||||
|
||||
# Previous call is an equivalent of next operations:
|
||||
#
|
||||
# database = sqlite3.connect(':memory:')
|
||||
# s3 = boto.s3.connection.S3Connection(aws_access_key_id='KEY',
|
||||
# aws_secret_access_key='SECRET')
|
||||
#
|
||||
# example.main.main(users_service=example.services.Users(db=database),
|
||||
# auth_service=example.services.Auth(db=database,
|
||||
# token_ttl=3600),
|
||||
# photos_service=example.services.Photos(db=database,
|
||||
# s3=s3))
|
|
@ -1,5 +1,7 @@
|
|||
"""Dependency injector injections unittests."""
|
||||
|
||||
import warnings
|
||||
|
||||
import unittest2 as unittest
|
||||
|
||||
from dependency_injector import injections
|
||||
|
@ -176,3 +178,25 @@ class InjectTests(unittest.TestCase):
|
|||
@injections.inject(arg1=123)
|
||||
class Test(object):
|
||||
"""Test class."""
|
||||
|
||||
|
||||
class InjectDeprecationTests(unittest.TestCase):
|
||||
"""Deprecation of `@inject()` tests."""
|
||||
|
||||
def test_deprecation_warning_on_usage(self):
|
||||
"""Test that DeprecationWarning is produced when `@inject` is used."""
|
||||
with warnings.catch_warnings(record=True) as caught_warnings:
|
||||
warnings.simplefilter('always')
|
||||
|
||||
@injections.inject(1)
|
||||
def _example(arg):
|
||||
pass
|
||||
|
||||
warnings.simplefilter('default')
|
||||
|
||||
self.assertEquals(len(caught_warnings), 1)
|
||||
self.assertEquals(caught_warnings[-1].category, DeprecationWarning)
|
||||
self.assertIn('Call to a deprecated decorator',
|
||||
str(caught_warnings[-1].message))
|
||||
self.assertIn('@dependency_injector.injections.inject',
|
||||
str(caught_warnings[-1].message))
|
||||
|
|
Loading…
Reference in New Issue
Block a user