Update MovieLister example

This commit is contained in:
Roman Mogilatov 2016-03-20 16:42:54 +02:00
parent 59615bc88b
commit d2603c3d17
8 changed files with 174 additions and 134 deletions

View File

@ -1,33 +1,45 @@
"""A naive example of dependency injection in Python.
Example implementation of dependency injection in Python from Martin Fowler's
article about dependency injection and inversion of control.
article about dependency injection and inversion of control:
http://www.martinfowler.com/articles/injection.html
This mini application uses ``movies`` library, that is configured to work with
csv file movies database.
"""
from movies.module import MoviesModule
from movies.components import CsvMovieFinder
from movies import MoviesModule
from movies import finders
from settings import MOVIES_CSV_PATH
from dependency_injector import catalogs
from dependency_injector import providers
from dependency_injector import injections
@catalogs.override(MoviesModule)
class MyMoviesModule(catalogs.DeclarativeCatalog):
"""Customized catalog of movie module components."""
"""Customized catalog of movies module components."""
movie_finder = providers.Factory(CsvMovieFinder,
movie_finder = providers.Factory(finders.CsvMovieFinder,
*MoviesModule.movie_finder.injections,
csv_file=MOVIES_CSV_PATH,
delimeter=',')
""":type: providers.Provider -> finders.CsvMovieFinder"""
def main():
"""Main function."""
movie_lister = MoviesModule.movie_lister()
@injections.inject(MoviesModule.movie_lister)
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: :py:class:`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')

View File

@ -1,20 +1,24 @@
"""A naive example of dependency injection in Python.
Example implementation of dependency injection in Python from Martin Fowler's
article about dependency injection and inversion of control.
article about dependency injection and inversion of control:
http://www.martinfowler.com/articles/injection.html
This mini application uses ``movies`` library, that is configured to work with
sqlite movies database.
"""
import sqlite3
from movies.module import MoviesModule
from movies.components import SqliteMovieFinder
from movies import MoviesModule
from movies import finders
from settings import MOVIES_DB_PATH
from dependency_injector import catalogs
from dependency_injector import providers
from dependency_injector import injections
class ApplicationModule(catalogs.DeclarativeCatalog):
@ -22,21 +26,29 @@ class ApplicationModule(catalogs.DeclarativeCatalog):
database = providers.Singleton(sqlite3.connect,
MOVIES_DB_PATH)
""":type: providers.Provider -> components.MovieFinder"""
""":type: providers.Provider -> sqlite3.Connection"""
@catalogs.override(MoviesModule)
class MyMoviesModule(catalogs.DeclarativeCatalog):
"""Customized catalog of movie module components."""
"""Customized catalog of movies module components."""
movie_finder = providers.Factory(SqliteMovieFinder,
movie_finder = providers.Factory(finders.SqliteMovieFinder,
*MoviesModule.movie_finder.injections,
database=ApplicationModule.database)
""":type: providers.Provider -> finders.SqliteMovieFinder"""
def main():
"""Main function."""
movie_lister = MoviesModule.movie_lister()
@injections.inject(MoviesModule.movie_lister)
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: :py:class:`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')

View File

@ -1 +1,23 @@
"""Movies package."""
from . import finders
from . import listers
from . import models
from dependency_injector import catalogs
from dependency_injector import providers
class MoviesModule(catalogs.DeclarativeCatalog):
"""Catalog of movies module components."""
movie_model = providers.DelegatedFactory(models.Movie)
""":type: providers.Provider -> models.Movie"""
movie_finder = providers.Factory(finders.MovieFinder,
movie_model=movie_model)
""":type: providers.Provider -> finders.MovieFinder"""
movie_lister = providers.Factory(listers.MovieLister,
movie_finder=movie_finder)
""":type: providers.Provider -> listers.MovieLister"""

View File

@ -1,100 +0,0 @@
"""Movies package components."""
import csv
class MovieLister(object):
"""Movie lister."""
def __init__(self, movie_finder):
"""Initializer."""
self.movie_finder = movie_finder
def movies_directed_by(self, director):
"""Return list of movies that were directed by certain person.
:param director: Director's name
:type director: str
:rtype: list[:py:class:`Movie`]
:return: List of movie instances.
"""
return [movie for movie in self.movie_finder.find_all()
if movie.director == director]
def movies_released_in(self, year):
"""Return list of movies that were released in certain year.
:param year: Release year
:type year: int
:rtype: list[:py:class:`Movie`]
:return: List of movie instances.
"""
return [movie for movie in self.movie_finder.find_all()
if movie.year == year]
class MovieFinder(object):
"""Movie finder."""
def find_all(self):
"""Return all found movies.
:rtype: list[:py:class:`Movie`]
:return: List of movie instances.
"""
raise NotImplementedError()
class CsvMovieFinder(MovieFinder):
"""Movie finder that fetches movies info from csv file."""
def __init__(self, csv_file, delimeter):
"""Initializer."""
self.csv_file = csv_file
self.delimeter = delimeter
def find_all(self):
"""Return all found movies.
:rtype: list[:py:class:`Movie`]
:return: List of movie instances.
"""
with open(self.csv_file) as csv_file:
reader = csv.reader(csv_file, delimiter=self.delimeter)
return [Movie(*row) for row in reader]
class SqliteMovieFinder(MovieFinder):
"""Movie finder that fetches movies info from sqlite database."""
def __init__(self, database):
"""Initializer."""
self.database = database
def find_all(self):
"""Return all found movies.
:rtype: list[:py:class:`Movie`]
:return: List of movie instances.
"""
with self.database:
rows = self.database.execute('SELECT name, year, director '
'FROM movies')
return [Movie(*row) for row in rows]
class Movie(object):
"""Movie model."""
def __init__(self, name, year, director):
"""Initializer."""
self.name = str(name)
self.year = int(year)
self.director = str(director)
def __repr__(self):
"""Return string representation of movie instance."""
return 'Movie(name={0}, year={1}, director={2})'.format(
repr(self.name), repr(self.year), repr(self.director))

View File

@ -0,0 +1,59 @@
"""Movie finders."""
import csv
class MovieFinder(object):
"""Movie finder."""
def __init__(self, movie_model):
"""Initializer."""
self.movie_model = movie_model
def find_all(self):
"""Return all found movies.
:rtype: list[:py:class:`Movie`]
:return: List of movie instances.
"""
raise NotImplementedError()
class CsvMovieFinder(MovieFinder):
"""Movie finder that fetches movies info from csv file."""
def __init__(self, movie_model, csv_file, delimeter):
"""Initializer."""
self.csv_file = csv_file
self.delimeter = delimeter
super(CsvMovieFinder, self).__init__(movie_model)
def find_all(self):
"""Return all found movies.
:rtype: list[:py:class:`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]
class SqliteMovieFinder(MovieFinder):
"""Movie finder that fetches movies info from sqlite database."""
def __init__(self, movie_model, database):
"""Initializer."""
self.database = database
super(SqliteMovieFinder, self).__init__(movie_model)
def find_all(self):
"""Return all found movies.
:rtype: list[:py:class:`Movie`]
:return: List of movie instances.
"""
with self.database:
rows = self.database.execute('SELECT name, year, director '
'FROM movies')
return [self.movie_model(*row) for row in rows]

View File

@ -0,0 +1,33 @@
"""Movie listers."""
class MovieLister(object):
"""Movie lister."""
def __init__(self, movie_finder):
"""Initializer."""
self.movie_finder = movie_finder
def movies_directed_by(self, director):
"""Return list of movies that were directed by certain person.
:param director: Director's name
:type director: str
:rtype: list[:py:class:`Movie`]
:return: List of movie instances.
"""
return [movie for movie in self.movie_finder.find_all()
if movie.director == director]
def movies_released_in(self, year):
"""Return list of movies that were released in certain year.
:param year: Release year
:type year: int
:rtype: list[:py:class:`Movie`]
:return: List of movie instances.
"""
return [movie for movie in self.movie_finder.find_all()
if movie.year == year]

View File

@ -0,0 +1,19 @@
"""Movie models."""
class Movie(object):
"""Movie model."""
def __init__(self, name, year, director):
"""Initializer."""
self.name = str(name)
self.year = int(year)
self.director = str(director)
def __repr__(self):
"""Return string representation of movie instance."""
return '{0}(name={1}, year={2}, director={3})'.format(
self.__class__.__name__,
repr(self.name),
repr(self.year),
repr(self.director))

View File

@ -1,17 +0,0 @@
"""Movies package dependency injection module."""
from . import components
from dependency_injector import catalogs
from dependency_injector import providers
class MoviesModule(catalogs.DeclarativeCatalog):
"""Catalog of movie module components."""
movie_finder = providers.Factory(components.MovieFinder)
""":type: providers.Provider -> components.MovieFinder"""
movie_lister = providers.Factory(components.MovieLister,
movie_finder=movie_finder)
""":type: providers.Provider -> components.MovieLister"""