Update movie lister example

This commit is contained in:
Roman Mogilatov 2016-09-22 14:40:45 +03:00
parent bff0e58f7f
commit 4e66c47f59
12 changed files with 146 additions and 118 deletions

View File

@ -11,8 +11,6 @@ Instructions for running:
.. code-block:: bash .. code-block:: bash
python create_db.py
python app_csv.py python app_csv.py
python app_db.py python app_db.py
python app_db_csv.py python app_db_csv.py

View File

@ -9,42 +9,40 @@ This mini application uses ``movies`` library, that is configured to work with
csv file movies database. 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
import movies.finders import movies.finders
import example.main
import example.db
import settings import settings
import dependency_injector.containers as containers
import dependency_injector.providers as providers
@containers.override(movies.MoviesModule) @containers.override(movies.MoviesModule)
class MyMoviesModule(containers.DeclarativeContainer): class MyMoviesModule(containers.DeclarativeContainer):
"""IoC container for overriding movies module component providers.""" """IoC container for overriding movies module component providers."""
movie_finder = providers.Factory(movies.finders.CsvMovieFinder, movie_finder = providers.Factory(movies.finders.CsvMovieFinder,
csv_file=settings.MOVIES_CSV_PATH, csv_file_path=settings.MOVIES_CSV_PATH,
delimeter=',', delimiter=',',
**movies.MoviesModule.movie_finder.kwargs) **movies.MoviesModule.movie_finder.kwargs)
@injections.inject(movies.MoviesModule.movie_lister) class CsvApplication(containers.DeclarativeContainer):
def main(movie_lister): """IoC container of csv application component providers."""
"""Main function.
This program prints info about all movies that were directed by different main = providers.Callable(example.main.main,
persons and then prints all movies that were released in 2015. movie_lister=movies.MoviesModule.movie_lister)
:param movie_lister: Movie lister instance init_db = providers.Callable(example.db.init_csv,
:type movie_lister: movies.listers.MovieLister movies_data=settings.MOVIES_SAMPLE_DATA,
""" csv_file_path=settings.MOVIES_CSV_PATH,
print movie_lister.movies_directed_by('Francis Lawrence') delimiter=',')
print movie_lister.movies_directed_by('Patricia Riggen')
print movie_lister.movies_directed_by('JJ Abrams')
print movie_lister.movies_released_in(2015)
if __name__ == '__main__': if __name__ == '__main__':
main() CsvApplication.init_db()
CsvApplication.main()

View File

@ -11,18 +11,20 @@ sqlite movies database.
import sqlite3 import sqlite3
import dependency_injector.containers as containers
import dependency_injector.providers as providers
import dependency_injector.injections as injections
import movies import movies
import movies.finders import movies.finders
import example.main
import example.db
import settings 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) 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.""" """IoC container for overriding movies module component providers."""
movie_finder = providers.Factory(movies.finders.SqliteMovieFinder, movie_finder = providers.Factory(movies.finders.SqliteMovieFinder,
database=ApplicationModule.database, database=ResourcesModule.database,
**movies.MoviesModule.movie_finder.kwargs) **movies.MoviesModule.movie_finder.kwargs)
@injections.inject(movies.MoviesModule.movie_lister) class DbApplication(containers.DeclarativeContainer):
def main(movie_lister): """IoC container of database application component providers."""
"""Main function.
This program prints info about all movies that were directed by different main = providers.Callable(example.main.main,
persons and then prints all movies that were released in 2015. movie_lister=movies.MoviesModule.movie_lister)
:param movie_lister: Movie lister instance init_db = providers.Callable(example.db.init_sqlite,
:type movie_lister: movies.listers.MovieLister movies_data=settings.MOVIES_SAMPLE_DATA,
""" database=ResourcesModule.database)
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)
if __name__ == '__main__': if __name__ == '__main__':
main() DbApplication.init_db()
DbApplication.main()

View File

@ -11,18 +11,20 @@ sqlite movies database and csv file movies database.
import sqlite3 import sqlite3
import dependency_injector.containers as containers
import dependency_injector.providers as providers
import dependency_injector.injections as injections
import movies import movies
import movies.finders import movies.finders
import example.main
import example.db
import settings 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) 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.""" """IoC container for overriding movies module component providers."""
movie_finder = providers.Factory(movies.finders.SqliteMovieFinder, movie_finder = providers.Factory(movies.finders.SqliteMovieFinder,
database=ApplicationModule.database, database=ResourcesModule.database,
**movies.MoviesModule.movie_finder.kwargs) **movies.MoviesModule.movie_finder.kwargs)
@ -41,31 +43,36 @@ class CsvMoviesModule(movies.MoviesModule):
"""IoC container for overriding movies module component providers.""" """IoC container for overriding movies module component providers."""
movie_finder = providers.Factory(movies.finders.CsvMovieFinder, movie_finder = providers.Factory(movies.finders.CsvMovieFinder,
csv_file=settings.MOVIES_CSV_PATH, csv_file_path=settings.MOVIES_CSV_PATH,
delimeter=',', delimiter=',',
**movies.MoviesModule.movie_finder.kwargs) **movies.MoviesModule.movie_finder.kwargs)
@injections.inject(db_movie_lister=DbMoviesModule.movie_lister) class DbApplication(containers.DeclarativeContainer):
@injections.inject(csv_movie_lister=CsvMoviesModule.movie_lister) """IoC container of database application component providers."""
def main(db_movie_lister, csv_movie_lister):
"""Main function.
This program prints info about all movies that were directed by different main = providers.Callable(example.main.main,
persons and then prints all movies that were released in 2015. movie_lister=DbMoviesModule.movie_lister)
:param db_movie_lister: Movie lister, configured to work with database init_db = providers.Callable(example.db.init_sqlite,
:type db_movie_lister: movies.listers.MovieLister 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__': if __name__ == '__main__':
main() DbApplication.init_db()
DbApplication.main()
CsvApplication.init_db()
CsvApplication.main()

View File

@ -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)

View File

@ -0,0 +1,5 @@
# Ignore everything in this directory
*
# Except this file:
!.gitignore

View File

@ -0,0 +1 @@
"""Example top-level package."""

View 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)

View 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))

View File

@ -12,13 +12,13 @@ concrete finder implementation in terms of library configuration.
Each of ``MoviesModule`` providers could be overridden. Each of ``MoviesModule`` providers could be overridden.
""" """
import dependency_injector.containers as containers
import dependency_injector.providers as providers
import movies.finders import movies.finders
import movies.listers import movies.listers
import movies.models import movies.models
import dependency_injector.containers as containers
import dependency_injector.providers as providers
class MoviesModule(containers.DeclarativeContainer): class MoviesModule(containers.DeclarativeContainer):
"""IoC container of movies module component providers.""" """IoC container of movies module component providers."""

View File

@ -33,20 +33,20 @@ class MovieFinder(object):
class CsvMovieFinder(MovieFinder): class CsvMovieFinder(MovieFinder):
"""Movie finder that fetches movies data from csv file.""" """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. """Initializer.
:param movie_model: Movie model's factory :param movie_model: Movie model's factory
:type movie_model: movies.models.Movie :type movie_model: movies.models.Movie
:param csv_file: Path to csv file with movies data :param csv_file_path: Path to csv file with movies data
:type csv_file: str :type csv_file_path: str
:param delimeter: Csv file's delimeter :param delimiter: Csv file's delimiter
:type delimeter: str :type delimiter: str
""" """
self._csv_file = csv_file self._csv_file_path = csv_file_path
self._delimeter = delimeter self._delimiter = delimiter
super(CsvMovieFinder, self).__init__(movie_model) super(CsvMovieFinder, self).__init__(movie_model)
def find_all(self): def find_all(self):
@ -55,9 +55,9 @@ class CsvMovieFinder(MovieFinder):
:rtype: list[movies.models.Movie] :rtype: list[movies.models.Movie]
:return: List of movie instances. :return: List of movie instances.
""" """
with open(self._csv_file) as csv_file: with open(self._csv_file_path) as csv_file:
reader = csv.reader(csv_file, delimiter=self._delimeter) csv_reader = csv.reader(csv_file, delimiter=self._delimiter)
return [self._movie_model(*row) for row in reader] return [self._movie_model(*row) for row in csv_reader]
class SqliteMovieFinder(MovieFinder): class SqliteMovieFinder(MovieFinder):

View File

@ -7,8 +7,11 @@ import os
DATA_DIR = os.path.abspath(os.path.dirname(__file__) + '/data') DATA_DIR = os.path.abspath(os.path.dirname(__file__) + '/data')
MOVIES_CSV_PATH = DATA_DIR + '/movies.csv' MOVIES_CSV_PATH = DATA_DIR + '/movies.csv'
MOVIES_CSV_DELIMETER = ','
MOVIES_DB_PATH = DATA_DIR + '/movies.db' 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'),
)