Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Python
__pycache__/
**/__pycache__/
*.py[cod]
*.pyo
*$py.class
*.so
.Python
Expand Down
42 changes: 15 additions & 27 deletions .launch/Dockerfile_base
Original file line number Diff line number Diff line change
@@ -1,52 +1,40 @@
# Build stage
ARG PYTHON_VERSION=3.12.11
FROM python:${PYTHON_VERSION}-slim AS builder
FROM python:3.12-slim AS builder

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1

WORKDIR /app

# Install build dependencies
RUN apt-get update && apt-get install -y \
build-essential \
&& rm -rf /var/lib/apt/lists/*

# Install poetry
RUN pip install --no-cache-dir poetry
# Install build tools and poetry
RUN apt-get update && apt-get install -y build-essential \
&& rm -rf /var/lib/apt/lists/* \
&& pip install --no-cache-dir poetry

# Copy dependency files
# Install dependencies
COPY pyproject.toml poetry.lock ./

# Configure poetry and install dependencies
RUN poetry config virtualenvs.create false \
&& poetry install --no-root --only=main

# Production stage
ARG PYTHON_VERSION=3.12
FROM python:${PYTHON_VERSION}-slim
FROM python:3.12-slim

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV PYTHONPATH=/app

# Install runtime dependencies only
RUN apt-get update && apt-get install -y \
libpq5 \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get clean
# Install runtime dependencies
RUN apt-get update && apt-get install -y libpq5 \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Get Python version for dynamic path
ARG PYTHON_VERSION=3.12
ENV PYTHON_SITE_PACKAGES=/usr/local/lib/python${PYTHON_VERSION}/site-packages

# Copy installed packages from builder stage
COPY --from=builder ${PYTHON_SITE_PACKAGES} ${PYTHON_SITE_PACKAGES}
# Copy Python packages and binaries from builder
COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY --from=builder /usr/local/bin /usr/local/bin

# Copy application code
COPY src/ ./src/
COPY alembic.ini ./

# Clean any cache files (safety backup)
RUN find ./src -name "*.pyc" -delete 2>/dev/null || true

2 changes: 1 addition & 1 deletion local_prepare.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ if [ ! "$(docker ps -aq -f name=${PROJECT_NAME_SLUG}_rabbitmq)" ]; then
-p $MESSAGE_BROKER_PORT:5672 \
-e RABBITMQ_DEFAULT_USER=$MESSAGE_BROKER_USER \
-e RABBITMQ_DEFAULT_PASS=$MESSAGE_BROKER_PASSWORD \
rabbitmq:3.11.6-management || true
rabbitmq:4.1.4-management-alpine || true
fi
echo " ✅ ${PROJECT_NAME_SLUG}_rabbitmq UP"

Expand Down
3 changes: 1 addition & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ aiokafka = "^0.12.0"
pytz = "^2025.2"
grpcio = "^1.69.0"
grpcio-tools = "^1.69.0"
greenlet = "^3.2.4"



[tool.poetry.group.dev.dependencies]
Expand Down
6 changes: 6 additions & 0 deletions src/app/application/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,11 @@ def auth_service(self) -> Type["src.app.application.services.auth_service.AuthSe

return AuthService

@property
def common_service(self) -> Type["src.app.application.services.common_service.CommonApplicationService"]:
from src.app.application.services.common_service import CommonApplicationService

return CommonApplicationService


container = ApplicationServicesContainer()
23 changes: 23 additions & 0 deletions src/app/application/services/common_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from src.app.infrastructure.messaging.mq_client import mq_client
from src.app.infrastructure.repositories.container import container as repo_container
from src.app.application.common.services.base import AbstractBaseApplicationService
from loguru import logger


class CommonApplicationService(AbstractBaseApplicationService):

@classmethod
async def is_healthy(cls) -> bool:
"""Checks if app infrastructure is up and healthy."""
try:
is_psql_healthy = await repo_container.common_psql_repository.is_healthy()

is_redis_healthy = await repo_container.common_redis_repository.is_healthy()

is_message_broker_healthy = await mq_client.is_healthy()

except Exception as ex:
logger.error(f"Application is not healthy. Reason: {ex}")
return False

return all([is_psql_healthy, is_redis_healthy, is_message_broker_healthy])
2 changes: 1 addition & 1 deletion src/app/infrastructure/messaging/clients/kafka_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ async def is_healthy(self) -> bool:
brokers = metadata.brokers() if callable(metadata.brokers) else metadata.brokers
return len(brokers) > 0
except Exception as ex:
logger.error(f"{ex}")
logger.warning(f"{ex}")
return False
finally:
await client.close()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ async def is_healthy(self) -> bool:
await connection_.close()
return True
except Exception as ex:
logger.error(f"{ex}")
logger.warning(f"{ex}")
return False

async def __get_connection(self) -> AbstractRobustConnection:
Expand Down
4 changes: 4 additions & 0 deletions src/app/infrastructure/repositories/base/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
from src.app.infrastructure.extensions.psql_ext.psql_ext import Base


class RepositoryError(Exception):
pass


class AbstractRepository(ABC):
pass

Expand Down
Loading