Added Ruff linting

This commit is contained in:
florian committed 2026-10-13 09:49:50 +02:00
1 parent 1254ac8cc4
commit 019e43b18c
5 files changed
+60 -28

No files matched your search

+28
View File
@@ -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",
]
+1
View File
@@ -0,0 +1 @@
ruff==0.17.0
+21 -20
View File
@@ -1,22 +1,23 @@
from fastapi import FastAPI, Depends, HTTPException, Request, Response import asyncio
import os
from contextlib import asynccontextmanager
from typing import Dict
import httpx
import uvicorn
from fastapi import Depends, FastAPI, HTTPException, Request
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from fastapi.security.api_key import APIKeyHeader from fastapi.security.api_key import APIKeyHeader
from starlette.exceptions import HTTPException as StarletteHTTPException
from typing import Dict
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from validator import verify_api_key from starlette.exceptions import HTTPException as StarletteHTTPException
from db_module import get_db, create_connection_pool, close_connection_pool, start_healthcheck_thread
from simple_logger_handler import setup_logger, LOG_LEVEL
from rabbitmq_handler import RabbitMQProducer
import uvicorn
from contextlib import asynccontextmanager
from metrics_server import REQUEST_COUNTER
import asyncio
from uvicorn_logger_config import LOGGING_CONFIG
from secret_manager import cleanup_secret_files
import httpx
import os
from db_module import close_connection_pool, create_connection_pool, get_db, start_healthcheck_thread
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__) logger = setup_logger(__name__)
api_key_header_internal = APIKeyHeader(name="X-API-Key-Internal") api_key_header_internal = APIKeyHeader(name="X-API-Key-Internal")
@@ -104,10 +105,10 @@ async def prometheus_middleware(request: Request, call_next):
return response return response
def verify_api_key_dependency_internal(db=Depends(get_db), api_key: str = Depends(api_key_header_internal)) -> str: def verify_api_key_dependency_internal(db=Depends(get_db), api_key: str = Depends(api_key_header_internal)) -> str:
logger.debug(f"Verifying internal API key: {api_key}") with db.cursor() as cursor:
cursor = db.cursor() cursor.execute("SELECT program_name, api_key FROM internal_api_keys WHERE status = 'active'")
cursor.execute("SELECT program_name, api_key FROM internal_api_keys WHERE status = 'active'") rows = cursor.fetchall()
for program_name, hashed_key in cursor.fetchall(): for program_name, hashed_key in rows:
if verify_api_key(api_key=api_key, hashed=hashed_key): if verify_api_key(api_key=api_key, hashed=hashed_key):
logger.debug(f"API key verified for program: {program_name}") logger.debug(f"API key verified for program: {program_name}")
return program_name return program_name
@@ -170,7 +171,7 @@ async def pull_notifications(
except (httpx.HTTPError, ValueError) as e: except (httpx.HTTPError, ValueError) as e:
logger.error(f"[FastAPI] Pull service failed for user_id={user_id}: {e!r}") logger.error(f"[FastAPI] Pull service failed for user_id={user_id}: {e!r}")
status = 504 if isinstance(e, httpx.TimeoutException) else 502 status = 504 if isinstance(e, httpx.TimeoutException) else 502
raise HTTPException(status_code=status, detail="Notification service unavailable") raise HTTPException(status_code=status, detail="Notification service unavailable") from e
logger.info(f"[FastAPI] Returning {len(messages)} message(s) for user_id={user_id}, has_more={has_more}") logger.info(f"[FastAPI] Returning {len(messages)} message(s) for user_id={user_id}, has_more={has_more}")
return PullResponse(messages=messages, count=len(messages), has_more=has_more) return PullResponse(messages=messages, count=len(messages), has_more=has_more)
+1 -1
View File
@@ -1,5 +1,5 @@
from fastapi import FastAPI, Response from fastapi import FastAPI, Response
from prometheus_client import generate_latest, CONTENT_TYPE_LATEST, Counter from prometheus_client import CONTENT_TYPE_LATEST, Counter, generate_latest
metrics_api = FastAPI(title="Metrics Server", description="Prometheus metrics endpoint") metrics_api = FastAPI(title="Metrics Server", description="Prometheus metrics endpoint")
+9 -7
View File
@@ -1,13 +1,15 @@
import asyncio import asyncio
import json
import os
from enum import IntEnum
from typing import NamedTuple
from urllib.parse import quote
import aio_pika import aio_pika
from aio_pika.exceptions import AMQPException, DeliveryError from aio_pika.exceptions import AMQPException, DeliveryError
from secret_manager import return_credentials from secret_manager import return_credentials
import os
from simple_logger_handler import setup_logger from simple_logger_handler import setup_logger
import json
from urllib.parse import quote
from typing import NamedTuple
from enum import IntEnum
logger = setup_logger(__name__) logger = setup_logger(__name__)
MAX_UNROUTABLE_ATTEMPTS = 3 MAX_UNROUTABLE_ATTEMPTS = 3
@@ -105,10 +107,10 @@ class RabbitMQProducer:
- Declares the user's pull queue first when the key is a pull key. - Declares the user's pull queue first when the key is a pull key.
- Returned/unroutable messages (DeliveryError) are retried up to - Returned/unroutable messages (DeliveryError) are retried up to
MAX_UNROUTABLE_ATTEMPTS times, then dropped with an error log. MAX_UNROUTABLE_ATTEMPTS times, then dropped with an error log.
- Connection errors are retried without limit after a 2 second pause. - Connection errors are retried without limit after a 2 second pause.
- Any other error (e.g. non-serializable payload) drops the message so the - Any other error (e.g. non-serializable payload) drops the message so the
loop keeps running. loop keeps running.
""" """
logger.debug("[RabbitMQ] Waiting for ready signal before flushing queue") logger.debug("[RabbitMQ] Waiting for ready signal before flushing queue")
await self._ready.wait() await self._ready.wait()