diff --git a/examples/miniapps/movie-lister/README.rst b/examples/miniapps/movie-lister/README.rst new file mode 100644 index 00000000..65576c6c --- /dev/null +++ b/examples/miniapps/movie-lister/README.rst @@ -0,0 +1,67 @@ +Movie lister - a naive example of dependency injection in Python +================================================================ + +This is a Python implementation of the dependency injection example from Martin Fowler's +article about dependency injection and inversion of control: + + http://www.martinfowler.com/articles/injection.html + +Create virtual environment: + +.. code-block:: bash + + virtualenv venv + . venv/bin/activate + +Install requirements: + +.. code-block:: bash + + pip install -r requirements.txt + +To run the application do: + +.. code-block:: bash + + MOVIE_STORAGE_TYPE=csv python -m movies + MOVIE_STORAGE_TYPE=sqlite python -m movies + +The output should be something like: + +.. code-block:: bash + + [Movie(name='The Hunger Games: Mockingjay - Part 2', year=2015, director='Francis Lawrence')] + [Movie(name='The 33', year=2015, director='Patricia Riggen')] + [Movie(name='Star Wars: Episode VII - The Force Awakens', year=2015, director='JJ Abrams')] + [Movie(name='The Hunger Games: Mockingjay - Part 2', year=2015, director='Francis Lawrence'), Movie(name='The 33', year=2015, director='Patricia Riggen'), Movie(name='Star Wars: Episode VII - The Force Awakens', year=2015, director='JJ Abrams')] + +To run the tests do: + +.. code-block:: bash + + pytest movies/tests.py --cov=movies + +The output should be something like: + +.. code-block:: + + platform darwin -- Python 3.8.3, pytest-5.4.3, py-1.9.0, pluggy-0.13.1 + plugins: cov-2.10.0 + collected 2 items + + movies/tests.py .. [100%] + + ---------- coverage: platform darwin, python 3.8.3-final-0 ----------- + Name Stmts Miss Cover + ------------------------------------------ + movies/__init__.py 0 0 100% + movies/__main__.py 15 15 0% + movies/containers.py 9 0 100% + movies/finders.py 9 0 100% + movies/fixtures.py 1 0 100% + movies/listers.py 8 0 100% + movies/models.py 7 1 86% + movies/storages.py 32 17 47% + movies/tests.py 24 0 100% + ------------------------------------------ + TOTAL 105 33 69% diff --git a/examples/miniapps/movie-lister/config.yml b/examples/miniapps/movie-lister/config.yml new file mode 100644 index 00000000..530061ce --- /dev/null +++ b/examples/miniapps/movie-lister/config.yml @@ -0,0 +1,8 @@ +storage: + + csv: + path: "data/movies.csv" + delimiter: "," + + sqlite: + path: "data/movies.db" diff --git a/examples/miniapps/movie_lister/data/.gitignore b/examples/miniapps/movie-lister/data/.gitignore similarity index 100% rename from examples/miniapps/movie_lister/data/.gitignore rename to examples/miniapps/movie-lister/data/.gitignore diff --git a/examples/miniapps/movie-lister/movies/__init__.py b/examples/miniapps/movie-lister/movies/__init__.py new file mode 100644 index 00000000..1c744ca5 --- /dev/null +++ b/examples/miniapps/movie-lister/movies/__init__.py @@ -0,0 +1 @@ +"""Top-level package.""" diff --git a/examples/miniapps/movie-lister/movies/__main__.py b/examples/miniapps/movie-lister/movies/__main__.py new file mode 100644 index 00000000..fbae50ff --- /dev/null +++ b/examples/miniapps/movie-lister/movies/__main__.py @@ -0,0 +1,23 @@ +"""Main module.""" + +from .containers import ApplicationContainer + + +def main(): + container = ApplicationContainer() + container.config.from_yaml('config.yml') + container.config.storage.type.from_env('MOVIE_STORAGE_TYPE') + + storage = container.storage() + fixtures = container.fixtures() + storage.load_all(fixtures) + + lister = container.lister() + print(lister.movies_directed_by('Francis Lawrence')) + print(lister.movies_directed_by('Patricia Riggen')) + print(lister.movies_directed_by('JJ Abrams')) + print(lister.movies_released_in(2015)) + + +if __name__ == '__main__': + main() diff --git a/examples/miniapps/movie-lister/movies/containers.py b/examples/miniapps/movie-lister/movies/containers.py new file mode 100644 index 00000000..b3e36eca --- /dev/null +++ b/examples/miniapps/movie-lister/movies/containers.py @@ -0,0 +1,39 @@ +"""Containers module.""" + +from dependency_injector import containers, providers + +from . import finders, listers, storages, models, fixtures + + +class ApplicationContainer(containers.DeclarativeContainer): + + config = providers.Configuration() + + fixtures = providers.Object(fixtures.MOVIES_SAMPLE_DATA) + + storage = providers.Singleton( + providers.Selector( + config.storage.type, + csv=providers.Factory( + storages.CsvMovieStorage, + options=config.storage[config.storage.type], + ), + sqlite=providers.Factory( + storages.SqliteMovieStorage, + options=config.storage[config.storage.type], + ), + ), + ) + + movie = providers.Factory(models.Movie) + + finder = providers.Factory( + finders.MovieFinder, + movie_factory=movie.provider, + movie_storage=storage, + ) + + lister = providers.Factory( + listers.MovieLister, + movie_finder=finder, + ) diff --git a/examples/miniapps/movie-lister/movies/finders.py b/examples/miniapps/movie-lister/movies/finders.py new file mode 100644 index 00000000..abb11074 --- /dev/null +++ b/examples/miniapps/movie-lister/movies/finders.py @@ -0,0 +1,23 @@ +"""Movie finders module.""" + +from typing import Callable, List + +from .models import Movie +from .storages import MovieStorage + + +class MovieFinder: + + def __init__( + self, + movie_factory: Callable[..., Movie], + movie_storage: MovieStorage, + ) -> None: + self._movie_factory = movie_factory + self._movie_storage = movie_storage + + def find_all(self) -> List[Movie]: + return [ + self._movie_factory(*row) + for row in self._movie_storage.get_all() + ] diff --git a/examples/miniapps/movie_lister/fixtures.py b/examples/miniapps/movie-lister/movies/fixtures.py similarity index 89% rename from examples/miniapps/movie_lister/fixtures.py rename to examples/miniapps/movie-lister/movies/fixtures.py index 0e8805be..8f7843d6 100644 --- a/examples/miniapps/movie_lister/fixtures.py +++ b/examples/miniapps/movie-lister/movies/fixtures.py @@ -1,8 +1,8 @@ """Fixtures module.""" -MOVIES_SAMPLE_DATA = ( +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'), -) +] diff --git a/examples/miniapps/movie-lister/movies/listers.py b/examples/miniapps/movie-lister/movies/listers.py new file mode 100644 index 00000000..36d254c2 --- /dev/null +++ b/examples/miniapps/movie-lister/movies/listers.py @@ -0,0 +1,21 @@ +"""Movie listers module.""" + +from .finders import MovieFinder + + +class MovieLister: + + def __init__(self, movie_finder: MovieFinder): + self._movie_finder = movie_finder + + def movies_directed_by(self, director): + return [ + movie for movie in self._movie_finder.find_all() + if movie.director == director + ] + + def movies_released_in(self, year): + return [ + movie for movie in self._movie_finder.find_all() + if movie.year == year + ] diff --git a/examples/miniapps/movie-lister/movies/models.py b/examples/miniapps/movie-lister/movies/models.py new file mode 100644 index 00000000..5041e71b --- /dev/null +++ b/examples/miniapps/movie-lister/movies/models.py @@ -0,0 +1,16 @@ +"""Movie module.""" + + +class Movie: + + def __init__(self, name: str, year: int, director: str): + self.name = str(name) + self.year = int(year) + self.director = str(director) + + def __repr__(self): + return '{0}(name={1}, year={2}, director={3})'.format( + self.__class__.__name__, + repr(self.name), + repr(self.year), + repr(self.director)) diff --git a/examples/miniapps/movie-lister/movies/storages.py b/examples/miniapps/movie-lister/movies/storages.py new file mode 100644 index 00000000..f37d35e3 --- /dev/null +++ b/examples/miniapps/movie-lister/movies/storages.py @@ -0,0 +1,55 @@ +"""Movie storages module.""" + +import csv +import sqlite3 +from typing import List, Tuple, Any + +Row = Tuple[Any] + + +class MovieStorage: + + def load_all(self, movie_data: List[Row]): + raise NotImplementedError() + + def get_all(self) -> List[Row]: + raise NotImplementedError() + + +class CsvMovieStorage(MovieStorage): + + def __init__(self, options) -> None: + self._csv_file_path = options.pop('path') + self._delimiter = options.pop('delimiter') + + def load_all(self, movie_data: List[Row]) -> None: + with open(self._csv_file_path, 'w') as csv_file: + csv.writer(csv_file, delimiter=self._delimiter).writerows(movie_data) + + def get_all(self) -> List[Row]: + with open(self._csv_file_path) as csv_file: + csv_reader = csv.reader(csv_file, delimiter=self._delimiter) + return [row for row in csv_reader] + + +class SqliteMovieStorage(MovieStorage): + + def __init__(self, options) -> None: + self._database = sqlite3.connect(database=options.pop('path')) + + def load_all(self, movie_data: List[Row]) -> None: + with self._database as db: + db.execute( + 'CREATE TABLE IF NOT EXISTS movies ' + '(name text, year int, director text)', + ) + db.execute('DELETE FROM movies') + db.executemany('INSERT INTO movies VALUES (?,?,?)', movie_data) + + def get_all(self) -> List[Row]: + with self._database as db: + rows = db.execute( + 'SELECT name, year, director ' + 'FROM movies', + ) + return [row for row in rows] diff --git a/examples/miniapps/movie-lister/movies/tests.py b/examples/miniapps/movie-lister/movies/tests.py new file mode 100644 index 00000000..2a2989a3 --- /dev/null +++ b/examples/miniapps/movie-lister/movies/tests.py @@ -0,0 +1,55 @@ +"""Tests module.""" + +from unittest import mock + +import pytest + +from .containers import ApplicationContainer + + +@pytest.fixture +def container(): + container = ApplicationContainer() + container.config.from_dict({ + 'storage': { + 'type': 'csv', + 'csv': { + 'path': '/fake-movies.csv', + 'delimiter': ',', + }, + 'sqlite': { + 'path': '/fake-movies.db', + }, + }, + }) + return container + + +def test_movies_directed_by(container): + storage_mock = mock.Mock() + storage_mock.get_all.return_value = [ + ('The 33', 2015, 'Patricia Riggen'), + ('The Jungle Book', 2016, 'Jon Favreau'), + ] + + with container.storage.override(storage_mock): + lister = container.lister() + movies = lister.movies_directed_by('Jon Favreau') + + assert len(movies) == 1 + assert movies[0].name == 'The Jungle Book' + + +def test_movies_released_in(container): + storage_mock = mock.Mock() + storage_mock.get_all.return_value = [ + ('The 33', 2015, 'Patricia Riggen'), + ('The Jungle Book', 2016, 'Jon Favreau'), + ] + + with container.storage.override(storage_mock): + lister = container.lister() + movies = lister.movies_released_in(2015) + + assert len(movies) == 1 + assert movies[0].name == 'The 33' diff --git a/examples/miniapps/movie-lister/requirements.txt b/examples/miniapps/movie-lister/requirements.txt new file mode 100644 index 00000000..72ff627e --- /dev/null +++ b/examples/miniapps/movie-lister/requirements.txt @@ -0,0 +1,4 @@ +dependency-injector +pyyaml +pytest +pytest-cov diff --git a/examples/miniapps/movie_lister/README.rst b/examples/miniapps/movie_lister/README.rst deleted file mode 100644 index 616b9106..00000000 --- a/examples/miniapps/movie_lister/README.rst +++ /dev/null @@ -1,16 +0,0 @@ -A naive example of dependency injection in Python -================================================= - -Example implementation of dependency injection on Python from Martin Fowler's -article about dependency injection and inversion of control: - -http://www.martinfowler.com/articles/injection.html - - -Instructions for running: - -.. code-block:: bash - - python app_csv.py - python app_db.py - python app_db_csv.py diff --git a/examples/miniapps/movie_lister/app_csv.py b/examples/miniapps/movie_lister/app_csv.py deleted file mode 100644 index 052492bc..00000000 --- a/examples/miniapps/movie_lister/app_csv.py +++ /dev/null @@ -1,49 +0,0 @@ -"""A naive example of dependency injection on Python. - -Example implementation of dependency injection in Python from Martin Fowler's -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. -""" - -import movies -import movies.finders - -import example.db -import example.main - -import settings -import fixtures - -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.""" - - finder = providers.Factory(movies.finders.CsvMovieFinder, - csv_file_path=settings.MOVIES_CSV_PATH, - delimiter=',', - **movies.MoviesModule.finder.kwargs) - - -class CsvApplication(containers.DeclarativeContainer): - """IoC container of csv application component providers.""" - - main = providers.Callable(example.main.main, - movie_lister=movies.MoviesModule.lister) - - init_db = providers.Callable(example.db.init_csv, - movies_data=fixtures.MOVIES_SAMPLE_DATA, - csv_file_path=settings.MOVIES_CSV_PATH, - delimiter=',') - - -if __name__ == '__main__': - CsvApplication.init_db() - CsvApplication.main() diff --git a/examples/miniapps/movie_lister/app_db.py b/examples/miniapps/movie_lister/app_db.py deleted file mode 100644 index dee6bdae..00000000 --- a/examples/miniapps/movie_lister/app_db.py +++ /dev/null @@ -1,55 +0,0 @@ -"""A naive example of dependency injection on Python. - -Example implementation of dependency injection in Python from Martin Fowler's -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 - -import movies -import movies.finders - -import example.db -import example.main - -import settings -import fixtures - -import dependency_injector.containers as containers -import dependency_injector.providers as providers - - -class ResourcesModule(containers.DeclarativeContainer): - """IoC container of application resource providers.""" - - database = providers.Singleton(sqlite3.connect, settings.MOVIES_DB_PATH) - - -@containers.override(movies.MoviesModule) -class MyMoviesModule(containers.DeclarativeContainer): - """IoC container for overriding movies module component providers.""" - - finder = providers.Factory(movies.finders.SqliteMovieFinder, - database=ResourcesModule.database, - **movies.MoviesModule.finder.kwargs) - - -class DbApplication(containers.DeclarativeContainer): - """IoC container of database application component providers.""" - - main = providers.Callable(example.main.main, - movie_lister=movies.MoviesModule.lister) - - init_db = providers.Callable(example.db.init_sqlite, - movies_data=fixtures.MOVIES_SAMPLE_DATA, - database=ResourcesModule.database) - - -if __name__ == '__main__': - DbApplication.init_db() - DbApplication.main() diff --git a/examples/miniapps/movie_lister/app_db_csv.py b/examples/miniapps/movie_lister/app_db_csv.py deleted file mode 100644 index 9822ff1d..00000000 --- a/examples/miniapps/movie_lister/app_db_csv.py +++ /dev/null @@ -1,80 +0,0 @@ -"""A naive example of dependency injection on Python. - -Example implementation of dependency injection in Python from Martin Fowler's -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 and csv file movies database. -""" - -import sqlite3 - -import movies -import movies.finders - -import example.db -import example.main - -import settings -import fixtures - -import dependency_injector.containers as containers -import dependency_injector.providers as providers - - -class ResourcesModule(containers.DeclarativeContainer): - """IoC container of application resource providers.""" - - database = providers.Singleton(sqlite3.connect, settings.MOVIES_DB_PATH) - - -@containers.copy(movies.MoviesModule) -class DbMoviesModule(movies.MoviesModule): - """IoC container for overriding movies module component providers.""" - - finder = providers.Factory(movies.finders.SqliteMovieFinder, - database=ResourcesModule.database, - **movies.MoviesModule.finder.kwargs) - - -@containers.copy(movies.MoviesModule) -class CsvMoviesModule(movies.MoviesModule): - """IoC container for overriding movies module component providers.""" - - finder = providers.Factory(movies.finders.CsvMovieFinder, - csv_file_path=settings.MOVIES_CSV_PATH, - delimiter=',', - **movies.MoviesModule.finder.kwargs) - - -class DbApplication(containers.DeclarativeContainer): - """IoC container of database application component providers.""" - - main = providers.Callable(example.main.main, - movie_lister=DbMoviesModule.lister) - - init_db = providers.Callable(example.db.init_sqlite, - movies_data=fixtures.MOVIES_SAMPLE_DATA, - database=ResourcesModule.database) - - -class CsvApplication(containers.DeclarativeContainer): - """IoC container of csv application component providers.""" - - main = providers.Callable(example.main.main, - movie_lister=CsvMoviesModule.lister) - - init_db = providers.Callable(example.db.init_csv, - movies_data=fixtures.MOVIES_SAMPLE_DATA, - csv_file_path=settings.MOVIES_CSV_PATH, - delimiter=',') - - -if __name__ == '__main__': - DbApplication.init_db() - DbApplication.main() - - CsvApplication.init_db() - CsvApplication.main() diff --git a/examples/miniapps/movie_lister/data/movies.csv b/examples/miniapps/movie_lister/data/movies.csv deleted file mode 100644 index 6cb91ddf..00000000 --- a/examples/miniapps/movie_lister/data/movies.csv +++ /dev/null @@ -1,3 +0,0 @@ -The Hunger Games: Mockingjay - Part 2,2015,Francis Lawrence -The 33,2015,Patricia Riggen -Star Wars: Episode VII - The Force Awakens,2015,JJ Abrams diff --git a/examples/miniapps/movie_lister/example/__init__.py b/examples/miniapps/movie_lister/example/__init__.py deleted file mode 100644 index bfa99aa2..00000000 --- a/examples/miniapps/movie_lister/example/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Example top-level package.""" diff --git a/examples/miniapps/movie_lister/example/db.py b/examples/miniapps/movie_lister/example/db.py deleted file mode 100644 index d519fb03..00000000 --- a/examples/miniapps/movie_lister/example/db.py +++ /dev/null @@ -1,35 +0,0 @@ -"""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) diff --git a/examples/miniapps/movie_lister/example/main.py b/examples/miniapps/movie_lister/example/main.py deleted file mode 100644 index c029226b..00000000 --- a/examples/miniapps/movie_lister/example/main.py +++ /dev/null @@ -1,17 +0,0 @@ -"""Example main module.""" - - -def main(movie_lister): - """Run application. - - 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)) diff --git a/examples/miniapps/movie_lister/movies/__init__.py b/examples/miniapps/movie_lister/movies/__init__.py deleted file mode 100644 index 73331b9a..00000000 --- a/examples/miniapps/movie_lister/movies/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -"""Movies package. - -Top-level package of movies library. This package contains IoC container of -movies module component providers - ``MoviesModule``. It is recommended to use -movies library functionality by fetching required instances from -``MoviesModule`` providers. - -``MoviesModule.finder`` is a factory that provides abstract component -``finders.MovieFinder``. This provider should be overridden by provider of -concrete finder implementation in terms of library configuration. - -Each of ``MoviesModule`` providers could be overridden. -""" - -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.""" - - movie = providers.Factory(movies.models.Movie) - - finder = providers.AbstractFactory(movies.finders.MovieFinder, - movie_model=movie.provider) - - lister = providers.Factory(movies.listers.MovieLister, - movie_finder=finder) diff --git a/examples/miniapps/movie_lister/movies/finders.py b/examples/miniapps/movie_lister/movies/finders.py deleted file mode 100644 index 557dcbdb..00000000 --- a/examples/miniapps/movie_lister/movies/finders.py +++ /dev/null @@ -1,87 +0,0 @@ -"""Movie finders module. - -This module contains all finder implementations. -""" - -import csv - - -class MovieFinder: - """Movie finder component. - - Movie finder component is responsible for fetching movies data from - various storage. - """ - - def __init__(self, movie_model): - """Initialize instance. - - :param movie_model: Movie model's factory - :type movie_model: movies.models.Movie - """ - self._movie_model = movie_model - - def find_all(self): - """Return all found movies. - - :rtype: list[movies.models.Movie] - :return: List of movie instances. - """ - raise NotImplementedError() - - -class CsvMovieFinder(MovieFinder): - """Movie finder that fetches movies data from csv file.""" - - def __init__(self, movie_model, csv_file_path, delimiter): - """Initialize instance. - - :param movie_model: Movie model's factory - :type movie_model: movies.models.Movie - - :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 - """ - self._csv_file_path = csv_file_path - self._delimiter = delimiter - super().__init__(movie_model) - - def find_all(self): - """Return all found movies. - - :rtype: list[movies.models.Movie] - :return: List of movie instances. - """ - 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): - """Movie finder that fetches movies data from sqlite database.""" - - def __init__(self, movie_model, database): - """Initialize instance. - - :param movie_model: Movie model's factory - :type movie_model: (object) -> movies.models.Movie - - :param database: Connection to sqlite database with movies data - :type database: sqlite3.Connection - """ - self._database = database - super().__init__(movie_model) - - def find_all(self): - """Return all found movies. - - :rtype: list[movies.models.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] diff --git a/examples/miniapps/movie_lister/movies/listers.py b/examples/miniapps/movie_lister/movies/listers.py deleted file mode 100644 index f00b22ba..00000000 --- a/examples/miniapps/movie_lister/movies/listers.py +++ /dev/null @@ -1,44 +0,0 @@ -"""Movie listers module. - -This module contains all lister implementations. -""" - - -class MovieLister: - """Movie lister component. - - Movie lister component provides several methods for filtering movies by - specific criteria. - """ - - def __init__(self, movie_finder): - """Initialize instance. - - :param movie_finder: Movie finder instance - :type movie_finder: movies.finders.MovieFinder - """ - 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[movies.models.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[movies.models.Movie] - :return: List of movie instances. - """ - return [movie for movie in self._movie_finder.find_all() - if movie.year == year] diff --git a/examples/miniapps/movie_lister/movies/models.py b/examples/miniapps/movie_lister/movies/models.py deleted file mode 100644 index c42d6903..00000000 --- a/examples/miniapps/movie_lister/movies/models.py +++ /dev/null @@ -1,36 +0,0 @@ -"""Movie models module. - -This module contains all model implementations. -""" - - -class Movie: - """Base movie model.""" - - def __init__(self, name, year, director): - """Initialize instance. - - :param name: Movie's name - :type name: str - - :param year: Year, when movie was released - :type year: int - - :param director: Name of person, that directed the movie - :type director: str - """ - self.name = str(name) - self.year = int(year) - self.director = str(director) - - def __repr__(self): - """Return string representation of movie instance. - - :rtype: str - :return: Movie's string representation. - """ - return '{0}(name={1}, year={2}, director={3})'.format( - self.__class__.__name__, - repr(self.name), - repr(self.year), - repr(self.director)) diff --git a/examples/miniapps/movie_lister/settings.py b/examples/miniapps/movie_lister/settings.py deleted file mode 100644 index 5aab4184..00000000 --- a/examples/miniapps/movie_lister/settings.py +++ /dev/null @@ -1,11 +0,0 @@ -"""Settings module. - -This module contains application's settings and constants. -""" - -import os - - -DATA_DIR = os.path.abspath(os.path.dirname(__file__) + '/data') -MOVIES_CSV_PATH = DATA_DIR + '/movies.csv' -MOVIES_DB_PATH = DATA_DIR + '/movies.db'