From 8a3630aca4fc83ee4cf1abe5167e4e73589bd78a Mon Sep 17 00:00:00 2001 From: Florian Date: Tue, 13 Oct 2026 11:32:19 +0200 Subject: [PATCH] Added Ruff linting --- pyproject.toml | 28 ++++++++++++++++++++++++++++ requirements-dev.txt | 1 + src/db.py | 10 ++++++---- src/device_token_repository.py | 2 +- src/metrics.py | 6 ++++-- src/rabbitmq_handler.py | 22 ++++++++++++---------- src/send_notification.py | 14 +++++++------- 7 files changed, 59 insertions(+), 24 deletions(-) create mode 100644 pyproject.toml create mode 100644 requirements-dev.txt diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..9f8f13d --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,28 @@ +[tool.ruff] +line-length = 120 +target-version = "py312" +[tool.ruff.lint] +select = [ + "E", "F", # pycodestyle errors, pyflakes (unused imports/variables, undefined names) + "I", # import sorting (replaces isort) + "B", # bugbear: likely bugs + "ASYNC", # async mistakes + "RUF006", # un-referenced asyncio.create_task (tasks can be garbage-collected) +] +ignore = ["E501"] + +[tool.ruff.lint.isort] +known-first-party = ["db_module", "metrics_server", "rabbitmq_handler", "secret_manager", + "simple_logger_handler", "uvicorn_logger_config", "validator"] + +[tool.ruff.format] +indent-style = "tab" + +[tool.ruff.lint.flake8-bugbear] +extend-immutable-calls = [ + "fastapi.Depends", + "fastapi.Query", + "fastapi.Header", + "fastapi.Body", + "fastapi.Security", +] \ No newline at end of file diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..92a80f4 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1 @@ +ruff==0.17.0 diff --git a/src/db.py b/src/db.py index 8e1da76..49f27d2 100644 --- a/src/db.py +++ b/src/db.py @@ -1,11 +1,13 @@ -from contextlib import asynccontextmanager -import aiomysql import asyncio -from secret_manager import return_credentials import os -from simple_logger_handler import setup_logger +from contextlib import asynccontextmanager + +import aiomysql import pymysql.err +from secret_manager import return_credentials +from simple_logger_handler import setup_logger + db_username = return_credentials("/etc/secrets/db_username") db_password = return_credentials("/etc/secrets/db_password") db_host = os.getenv("BACKEND_PN_DB_HOST","localhost") diff --git a/src/device_token_repository.py b/src/device_token_repository.py index ff8bb54..8a9ada5 100644 --- a/src/device_token_repository.py +++ b/src/device_token_repository.py @@ -41,7 +41,7 @@ async def remove_inactive_push_token(uuid :str, db_manager): async with db_manager.acquire() as conn: async with conn.cursor() as cur: await cur.execute("UPDATE device_tokens SET status='expired' WHERE token_id=%s", - (uuid,)) + (uuid,)) success = cur.rowcount > 0 logger.debug(f"[DB] Token expiration for uuid={uuid} success={success}") return success diff --git a/src/metrics.py b/src/metrics.py index 2666d32..8f35b11 100644 --- a/src/metrics.py +++ b/src/metrics.py @@ -1,7 +1,9 @@ -from prometheus_client import Counter, Gauge, start_http_server -from simple_logger_handler import setup_logger import asyncio +from prometheus_client import Counter, Gauge, start_http_server + +from simple_logger_handler import setup_logger + logger = setup_logger(__name__) MSG_PUBLISHED = Counter( diff --git a/src/rabbitmq_handler.py b/src/rabbitmq_handler.py index e43778c..274d11c 100644 --- a/src/rabbitmq_handler.py +++ b/src/rabbitmq_handler.py @@ -1,16 +1,18 @@ import asyncio +import json +import os +import signal + import aio_pika from aio_pika.exceptions import AMQPException -from secret_manager import return_credentials, cleanup_secret_files -from secret_manager.fernet_encryption import decrypt_token -from device_token_repository import database_lookup_by_user_id, remove_inactive_push_token, database_lookup_by_uuid -import os -from simple_logger_handler import setup_logger -import json -from db import db_manager -from send_notification import send_notification -import signal + import metrics +from db import db_manager +from device_token_repository import database_lookup_by_user_id, database_lookup_by_uuid, remove_inactive_push_token +from secret_manager import cleanup_secret_files, return_credentials +from secret_manager.fernet_encryption import decrypt_token +from send_notification import send_notification +from simple_logger_handler import setup_logger logger = setup_logger(__name__) @@ -70,7 +72,7 @@ class RabbitMQConsumer: logger.debug(f"[RabbitMQ] DLQ queue '{self.dlq_queue_name}' declared.") metrics.start_metrics_server(port=9000) - logger.debug(f"[Metrics] Prometheus metrics server started on port 9000.") + logger.debug("[Metrics] Prometheus metrics server started on port 9000.") self._metric_tasks = [ asyncio.create_task(metrics.update_queue_gauge(self.channel, self.queue_name)), diff --git a/src/send_notification.py b/src/send_notification.py index 956dc9c..7f696b0 100644 --- a/src/send_notification.py +++ b/src/send_notification.py @@ -1,6 +1,7 @@ -import aiohttp -import aiodns import asyncio + +import aiohttp + from simple_logger_handler import setup_logger API_ENDPOINT="https://exp.host/--/api/v2/push/send" @@ -15,15 +16,15 @@ retryable_exceptions = ( ) -async def send_notification(message: dict, push_tokens, max_retries: int = 5, timeout: int = 5): +async def send_notification(message: dict, push_tokens, max_retries: int = 5): logger.debug(f"[Notification] Sending to {len(push_tokens)} push tokens") results = {} for uuid, token in push_tokens.items(): logger.debug(f"[Notification] Preparing to send to uuid={uuid}") - results[uuid] = await _send_to_token(token, uuid, message, max_retries, timeout) + results[uuid] = await _send_to_token(token, uuid, message, max_retries) return results -async def _send_to_token(token: str, uuid:str , message: dict, max_retries: int, timeout: int): +async def _send_to_token(token: str, uuid:str , message: dict, max_retries: int): payload = create_payload(token, message) logger.debug(f"[Notification] Payload for uuid={uuid}: {payload}") @@ -36,8 +37,7 @@ async def _send_to_token(token: str, uuid:str , message: dict, max_retries: int, async with session.post( url=API_ENDPOINT, json=payload, - headers={"Content-Type": "application/json"}, - timeout=timeout + headers={"Content-Type": "application/json"} ) as response: response.raise_for_status() data = await response.json()