From 3df54ed3cf798688fb264425e043b0923e46339a Mon Sep 17 00:00:00 2001 From: Florian Date: Sun, 18 Oct 2026 09:08:51 +0000 Subject: [PATCH] Upgraded modules (#8) Reviewed-on: https://git.gansejunge.com/notifier/backend-api-internal/pulls/8 - Upgraded modules Co-authored-by: Florian --- requirements.txt | 54 ++++++++++++++++++++--------------------- src/main.py | 37 ++++++++++++++-------------- src/rabbitmq_handler.py | 6 ++--- 3 files changed, 48 insertions(+), 49 deletions(-) diff --git a/requirements.txt b/requirements.txt index c0b23f3..628b741 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,34 +1,34 @@ --extra-index-url https://git.gansejunge.com/api/packages/notifier/pypi/simple/ -aio-pika==9.5.7 -aiormq==6.9.0 -annotated-types==0.7.0 -anyio==4.11.0 +aio-pika==10.1.1 +aiormq==7.2.2 +annotated-doc==0.0.5 +annotated-types==0.8.0 +anyio==4.15.1 argon2-cffi==25.1.0 -argon2-cffi-bindings==25.1.0 +argon2-cffi-bindings==26.1.0 certifi==2026.7.22 -cffi==2.0.0 -click==8.3.0 -fastapi==0.119.0 +cffi==2.1.1 +click==8.5.0 +fastapi==0.143.3 h11==0.16.0 httpcore==1.0.9 httpx==0.28.1 -idna==3.11 -lib-db-module==0.2.0 -lib-secret-manager==0.2.0 -lib-uvicorn-config==0.2.0 -multidict==6.7.0 +idna==3.20 +lib-db-module==0.3.0 +lib-secret-manager==0.3.1 +multidict==7.1.0 mysql-connector-python==9.4.0 -pamqp==3.3.0 -prometheus_client==0.23.1 -propcache==0.4.1 -pycparser==2.23 -pydantic==2.12.0 -pydantic_core==2.41.1 -python-json-logger==4.0.0 -simple-logger-handler==0.1.0 -sniffio==1.3.1 -starlette==0.48.0 -typing-inspection==0.4.2 -typing_extensions==4.15.0 -uvicorn==0.37.0 -yarl==1.22.0 +opentelemetry-api==1.45.1 +pamqp==4.0.1 +prometheus_client==0.26.0 +propcache==0.5.4 +pycparser==3.11 +pydantic==2.14.1 +pydantic_core==2.50.1 +python-json-logger==4.2.0 +simple-logger-handler==0.2.1 +starlette==1.8.0 +typing-inspection==0.4.4 +typing_extensions==4.16.0 +uvicorn==0.54.0 +yarl==1.25.1 \ No newline at end of file diff --git a/src/main.py b/src/main.py index e4d1b1e..cf2af73 100644 --- a/src/main.py +++ b/src/main.py @@ -16,14 +16,13 @@ from metrics_server import REQUEST_COUNTER from rabbitmq_handler import RabbitMQProducer from secret_manager import cleanup_secret_files from simple_logger_handler import LOG_LEVEL, setup_logger -from uvicorn_logger_config import LOGGING_CONFIG from validator import verify_api_key logger = setup_logger(__name__) api_key_header_internal = APIKeyHeader(name="X-API-Key-Internal") class Notification(BaseModel): - user_id : int = Field(gt=0) #ToDo fix among all services + user_id : int = Field(gt=0) message : Dict class PullResponse(BaseModel): @@ -36,12 +35,12 @@ class PullRequest(BaseModel): @asynccontextmanager async def lifespan(app: FastAPI): - logger.info("Starting application...") + logger.info("[FastAPI] Starting application...") - logger.info("Creating MySQL connection pool...") + logger.info("[FastAPI] Creating MySQL connection pool...") create_connection_pool("ApiInternalPool") start_healthcheck_thread() - logger.info("MySQL healthcheck thread started.") + logger.info("[FastAPI] MySQL healthcheck thread started.") producer = RabbitMQProducer() PULL_SERVICE_URL = os.getenv( @@ -50,7 +49,7 @@ async def lifespan(app: FastAPI): ) try: - logger.info("Starting RabbitMQ producer...") + logger.info("[FastAPI] Starting RabbitMQ producer...") await producer.connect() app.state.rmq_producer = producer logger.info("[FastAPI] RabbitMQ producer initialized.") @@ -71,10 +70,10 @@ async def lifespan(app: FastAPI): yield finally: - logger.info("Closing RabbitMQ producer...") + logger.info("[FastAPI] Closing RabbitMQ producer...") await producer.close() - logger.info("Closing MySQL connection pool...") + logger.info("[FastAPI] Closing MySQL connection pool...") close_connection_pool() await app.state.http_client.aclose() @@ -96,11 +95,11 @@ async def prometheus_middleware(request: Request, call_next): status = response.status_code logger.debug(f"Request processed with status: {status}") except Exception as e: - logger.exception(f"Exception during request processing: {e}") + logger.exception(f"[FastAPI] Exception during request processing: {e}") raise finally: REQUEST_COUNTER.labels(request.method, request.url.path, status).inc() - logger.debug(f"Prometheus counter incremented: {request.method} {request.url.path} {status}") + logger.debug(f"[FastAPI] Prometheus counter incremented: {request.method} {request.url.path} {status}") return response def verify_api_key_dependency_internal(db=Depends(get_db), api_key: str = Depends(api_key_header_internal)) -> str: @@ -109,9 +108,9 @@ def verify_api_key_dependency_internal(db=Depends(get_db), api_key: str = Depend rows = cursor.fetchall() for program_name, hashed_key in rows: if verify_api_key(api_key=api_key, hashed=hashed_key): - logger.debug(f"API key verified for program: {program_name}") + logger.debug(f"[FastAPI] API key verified for program: {program_name}") return program_name - logger.warning("Internal API key verification failed") + logger.warning("[FastAPI] Internal API key verification failed") raise HTTPException(status_code=403, detail="Unauthorized") @api.exception_handler(StarletteHTTPException) @@ -127,7 +126,7 @@ async def custom_http_exception_handler(request,exc): content={"detail": exc.detail} ) -@api.post("/internal/receive-notifications") #ToDo fix among all services +@api.post("/internal/receive-notifications") async def receive_notifications( notification_data: Notification, request: Request, @@ -135,8 +134,8 @@ async def receive_notifications( program_name: str = Depends(verify_api_key_dependency_internal) ): - logger.info(f"Received notifcation data from {program_name} for RMQ") - logger.debug(f"Notification data: {notification_data}") + logger.info(f"[FastAPI] Received notifcation data from {program_name} for RMQ") + logger.debug(f"[FastAPI] Notification data: {notification_data}") await request.app.state.rmq_producer.publish( notification_data.user_id, notification_data.message @@ -168,15 +167,15 @@ async def pull_notifications( return data async def start_servers(): - logger.debug("Starting FastAPI and metrics servers") - config_main = uvicorn.Config("main:api", host="0.0.0.0", port=8101, log_level=LOG_LEVEL.lower(), log_config=LOGGING_CONFIG) - config_metrics = uvicorn.Config("metrics_server:metrics_api", host="0.0.0.0", port=9000, log_level=LOG_LEVEL.lower(), log_config=LOGGING_CONFIG) + logger.info("[Server] Starting main API (port 8101) and metrics server (port 9000)...") + config_main = uvicorn.Config("main:api", host="0.0.0.0", port=8101, log_level=LOG_LEVEL.lower(), log_config=None) + config_metrics = uvicorn.Config("metrics_server:metrics_api", host="0.0.0.0", port=9000, log_level=LOG_LEVEL.lower(), log_config=None) server_main = uvicorn.Server(config_main) server_metrics = uvicorn.Server(config_metrics) await asyncio.gather(server_main.serve(), server_metrics.serve()) - logger.debug("Servers started") + logger.info("[Server] Both servers have stopped.") if __name__ == "__main__": asyncio.run(start_servers()) diff --git a/src/rabbitmq_handler.py b/src/rabbitmq_handler.py index ae57bdd..b4aae2f 100644 --- a/src/rabbitmq_handler.py +++ b/src/rabbitmq_handler.py @@ -8,7 +8,7 @@ from urllib.parse import quote import aio_pika from aio_pika.exceptions import AMQPException, DeliveryError -from secret_manager import return_credentials +from secret_manager import get_secret from simple_logger_handler import setup_logger logger = setup_logger(__name__) @@ -50,8 +50,8 @@ class RabbitMQProducer: self._ready = asyncio.Event() async def connect(self): - username = return_credentials("/etc/secrets/rmq_username") - password = return_credentials("/etc/secrets/rmq_password") + username = get_secret(os.getenv("RMQ_USERNAME",""),"/etc/secrets/rmq_username") + password = get_secret(os.getenv("RMQ_PASSWORD",""),"/etc/secrets/rmq_password") url = ( f"amqp://{quote(username, safe='')}:{quote(password, safe='')}" f"@{self.rmq_host}/{quote(self.rmq_vhost, safe='')}"