mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 09:57:37 +03:00 
			
		
		
		
	Rework movie lister example app
This commit is contained in:
		
							parent
							
								
									ca18fea26c
								
							
						
					
					
						commit
						a21c0c6160
					
				
							
								
								
									
										67
									
								
								examples/miniapps/movie-lister/README.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								examples/miniapps/movie-lister/README.rst
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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%
 | 
				
			||||||
							
								
								
									
										8
									
								
								examples/miniapps/movie-lister/config.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								examples/miniapps/movie-lister/config.yml
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					storage:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  csv:
 | 
				
			||||||
 | 
					    path: "data/movies.csv"
 | 
				
			||||||
 | 
					    delimiter: ","
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  sqlite:
 | 
				
			||||||
 | 
					    path: "data/movies.db"
 | 
				
			||||||
							
								
								
									
										1
									
								
								examples/miniapps/movie-lister/movies/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								examples/miniapps/movie-lister/movies/__init__.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					"""Top-level package."""
 | 
				
			||||||
							
								
								
									
										23
									
								
								examples/miniapps/movie-lister/movies/__main__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								examples/miniapps/movie-lister/movies/__main__.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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()
 | 
				
			||||||
							
								
								
									
										39
									
								
								examples/miniapps/movie-lister/movies/containers.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								examples/miniapps/movie-lister/movies/containers.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
							
								
								
									
										23
									
								
								examples/miniapps/movie-lister/movies/finders.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								examples/miniapps/movie-lister/movies/finders.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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()
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,8 @@
 | 
				
			||||||
"""Fixtures module."""
 | 
					"""Fixtures module."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MOVIES_SAMPLE_DATA = (
 | 
					MOVIES_SAMPLE_DATA = [
 | 
				
			||||||
    ('The Hunger Games: Mockingjay - Part 2', 2015, 'Francis Lawrence'),
 | 
					    ('The Hunger Games: Mockingjay - Part 2', 2015, 'Francis Lawrence'),
 | 
				
			||||||
    ('The 33', 2015, 'Patricia Riggen'),
 | 
					    ('The 33', 2015, 'Patricia Riggen'),
 | 
				
			||||||
    ('Star Wars: Episode VII - The Force Awakens', 2015, 'JJ Abrams'),
 | 
					    ('Star Wars: Episode VII - The Force Awakens', 2015, 'JJ Abrams'),
 | 
				
			||||||
)
 | 
					]
 | 
				
			||||||
							
								
								
									
										21
									
								
								examples/miniapps/movie-lister/movies/listers.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								examples/miniapps/movie-lister/movies/listers.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
							
								
								
									
										16
									
								
								examples/miniapps/movie-lister/movies/models.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								examples/miniapps/movie-lister/movies/models.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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))
 | 
				
			||||||
							
								
								
									
										55
									
								
								examples/miniapps/movie-lister/movies/storages.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								examples/miniapps/movie-lister/movies/storages.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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]
 | 
				
			||||||
							
								
								
									
										55
									
								
								examples/miniapps/movie-lister/movies/tests.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								examples/miniapps/movie-lister/movies/tests.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -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'
 | 
				
			||||||
							
								
								
									
										4
									
								
								examples/miniapps/movie-lister/requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								examples/miniapps/movie-lister/requirements.txt
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,4 @@
 | 
				
			||||||
 | 
					dependency-injector
 | 
				
			||||||
 | 
					pyyaml
 | 
				
			||||||
 | 
					pytest
 | 
				
			||||||
 | 
					pytest-cov
 | 
				
			||||||
| 
						 | 
					@ -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
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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()
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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()
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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()
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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
 | 
					 | 
				
			||||||
		
		
			
  | 
| 
						 | 
					@ -1 +0,0 @@
 | 
				
			||||||
"""Example top-level package."""
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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))
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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]
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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]
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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))
 | 
					 | 
				
			||||||
| 
						 | 
					@ -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'
 | 
					 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user