diff --git a/Dockerfile b/Dockerfile index 09858f3..fcddb6c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,11 @@ RUN mkdir -p /usr/src/fastfood WORKDIR /usr/src/fastfood -COPY . . +COPY ./example.env . + +COPY ./poetry.lock . + +COPY ./pyproject.toml . RUN touch /usr/src/RUN_IN_DOCKER diff --git a/bg_tasks/updater.py b/bg_tasks/updater.py index 339b434..d1a13f7 100644 --- a/bg_tasks/updater.py +++ b/bg_tasks/updater.py @@ -12,7 +12,9 @@ from fastfood.models import Dish, Menu, SubMenu file = os.path.join(os.path.curdir, 'admin', 'Menu.xlsx') -redis = redis.Redis(host='127.0.0.1', port=6379, db=0) +redis = redis.Redis( + host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=settings.REDIS_DB +) async_engine = create_async_engine(settings.DATABASE_URL_asyncpg) async_session_maker = async_sessionmaker( @@ -22,7 +24,10 @@ async_session_maker = async_sessionmaker( ) -async def refresh_cache(disconts: dict): +async def refresh_cache(disconts: dict) -> None: + """Очищает кэш при обновлении БД и ставит отметку времени обновления + и сохраняет данные скидок на товар + """ await redis.flushall() for key in disconts.keys(): @@ -50,7 +55,6 @@ async def is_changed_xls() -> bool: async def xlsx_to_dict() -> dict: """Парсит Menu.xlsx в словарь""" - print('run dumping xlsx_to_dict') wb = openpyxl.load_workbook(file).worksheets[0] data = {} @@ -89,7 +93,9 @@ async def xlsx_to_dict() -> dict: async def refresh_all_data(data: dict) -> dict[UUID, int | float]: - """Чистит кэш удаляем старые данные и пушим новые""" + """Удаляет старые данные и сохраняет новые. + Создает и возвращает список со скидками с привязкой по UUID товара + """ disconts = {} @@ -133,10 +139,10 @@ async def refresh_all_data(data: dict) -> dict[UUID, int | float]: return disconts -async def main(): +async def main() -> None: + """Главная функция фоновой задачи""" changed = await is_changed_xls() if changed: - print('Файл изменен, обновляю базу') menu_data = await xlsx_to_dict() discont_data = await refresh_all_data(menu_data) await refresh_cache(discont_data) diff --git a/compose_app.yml b/compose_app.yml index a8ad9a8..46203c4 100644 --- a/compose_app.yml +++ b/compose_app.yml @@ -57,4 +57,35 @@ services: restart: always + volumes: + - .:/usr/src/fastfood + command: /bin/bash -c 'poetry run python /usr/src/fastfood/manage.py --run-test-server' + + celery: + container_name: celery + + build: + context: . + + env_file: + - .env + + depends_on: + - rabbitmq + - db + - app + - redis + + volumes: + - .:/usr/src/fastfood + + command: /bin/bash -c 'poetry run python /usr/src/fastfood/manage.py --run-selery' + + rabbitmq: + container_name: rabbit + + image: "rabbitmq:management" + + ports: + - 5672:5672 diff --git a/example.env b/example.env index 73ef17e..51d748a 100644 --- a/example.env +++ b/example.env @@ -1,7 +1,14 @@ -DB_HOST=db -DB_PORT=5432 +# PosgreSQL адрес сервера +POSTGRES_HOST=127.0.0.1 +POSTGRES_PORT=5432 +# Пользователь БД Postgres POSTGRES_USER=testuser POSTGRES_PASSWORD=test +# БД рабочая и тестовая POSTGRES_DB=fastfood_db -POSTGRES_DB_TEST=testdb -REDIS_DB=redis://localhost +POSTGRES_DB_TEST=fastfood_db_test + +# Redis +REDIS_HOST=127.0.0.1 +REDIS_PORT=6379 +REDIS_DB=0 diff --git a/fastfood/config.py b/fastfood/config.py index e180dc7..7420230 100644 --- a/fastfood/config.py +++ b/fastfood/config.py @@ -4,13 +4,17 @@ from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): - DB_HOST: str = '' - DB_PORT: int = 5432 + # Конфиг PostgreSql + POSTGRES_HOST: str = '' + POSTGRES_PORT: int = 5432 POSTGRES_DB: str = '' POSTGRES_PASSWORD: str = '' POSTGRES_USER: str = '' POSTGRES_DB_TEST: str = '' - REDIS_DB: str = '' + # Конфиг Redis + REDIS_HOST: str = '' + REDIS_PORT: int = 6379 + REDIS_DB: int = 0 @property def DATABASE_URL_asyncpg(self) -> str: @@ -18,19 +22,18 @@ class Settings(BaseSettings): Возвращает строку подключения к БД необходимую для SQLAlchemy """ # Проверяем, в DOCKER или нет - file_path = '/usr/src/RUN_IN_DOCKER' if os.path.exists(file_path): return ( 'postgresql+asyncpg://' f'{self.POSTGRES_USER}:{self.POSTGRES_PASSWORD}' - f'@db:{self.DB_PORT}/{self.POSTGRES_DB}' + f'@db:5432/{self.POSTGRES_DB}' ) return ( 'postgresql+asyncpg://' f'{self.POSTGRES_USER}:{self.POSTGRES_PASSWORD}' - f'@{self.DB_HOST}:{self.DB_PORT}/{self.POSTGRES_DB}' + f'@{self.POSTGRES_HOST}:{self.POSTGRES_PORT}/{self.POSTGRES_DB}' ) @property @@ -43,22 +46,25 @@ class Settings(BaseSettings): return ( 'postgresql+asyncpg://' f'{self.POSTGRES_USER}:{self.POSTGRES_PASSWORD}' - f'@db:{self.DB_PORT}/{self.POSTGRES_DB_TEST}' + f'@db:5432/{self.POSTGRES_DB_TEST}' ) return ( 'postgresql+asyncpg://' f'{self.POSTGRES_USER}:{self.POSTGRES_PASSWORD}' - f'@{self.DB_HOST}:{self.DB_PORT}/{self.POSTGRES_DB_TEST}' + f'@{self.POSTGRES_HOST}:{self.POSTGRES_PORT}/{self.POSTGRES_DB_TEST}' ) @property def REDIS_URL(self): + """ + Возвращает строку подключения к REDIS + """ file_path = '/usr/src/RUN_IN_DOCKER' if os.path.exists(file_path): return 'redis://redis:6379/0' - return self.REDIS_DB + return f'redis://{self.REDIS_HOST}:{self.REDIS_PORT}/{self.REDIS_DB}' model_config = SettingsConfigDict(env_file='.env') diff --git a/manage.py b/manage.py index cb5762c..2ef59b1 100644 --- a/manage.py +++ b/manage.py @@ -42,6 +42,10 @@ async def recreate() -> None: if __name__ == '__main__': + if '--run-celery' in sys.argv: + celery_worker_process.start() + celery_beat_process.start() + if '--run-server' in sys.argv: pass