diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80639cf..314a67f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: pip install -r requirements.txt - name: Lint - run: flake8 bot/ discovery/ dashboard/ --max-line-length=120 --ignore=E501,W503 + run: flake8 bot/ discovery/ dashboard/ - name: Test run: pytest tests/ -v --tb=short diff --git a/bot/agent_server.py b/bot/agent_server.py index f1fef3e..e138569 100644 --- a/bot/agent_server.py +++ b/bot/agent_server.py @@ -16,7 +16,9 @@ def create_agent_server(agents: dict, snmp_devices: dict, config: dict) -> web.Application: """Create the aiohttp app for agent communication.""" - secret = config.get("server", {}).get("secret_key", "") + # NOTE: config carries a server.secret_key, but nothing in this module uses it. + # It was assigned and never read (flake8 F841). Left as a comment rather than a + # silent read so a future implementer sees the intent; remove if unused for good. app = web.Application() diff --git a/bot/handlers.py b/bot/handlers.py index a322bf3..2c82726 100644 --- a/bot/handlers.py +++ b/bot/handlers.py @@ -21,6 +21,7 @@ # ── Auth Decorator ──────────────────────────────────────────────────────────── + def admin_only(func): @wraps(func) async def wrapper(update: Update, ctx: ContextTypes.DEFAULT_TYPE, *args, **kwargs): diff --git a/bot/main.py b/bot/main.py index 71aeed3..1769208 100644 --- a/bot/main.py +++ b/bot/main.py @@ -20,7 +20,8 @@ # Add project root to path sys.path.insert(0, str(Path(__file__).parent.parent)) -from bot.handlers import ( +# These must follow the sys.path.insert above, so E402 is expected here. +from bot.handlers import ( # noqa: E402 agents_handler, alert_handler, callback_handler, @@ -31,9 +32,9 @@ status_handler, windows_handler, ) -from bot.scheduler import setup_scheduler -from discovery.network_scanner import NetworkScanner -from discovery.snmp_scanner import SNMPScanner +from bot.scheduler import setup_scheduler # noqa: E402 +from discovery.network_scanner import NetworkScanner # noqa: E402 +from discovery.snmp_scanner import SNMPScanner # noqa: E402 # ── Logging ────────────────────────────────────────────────────────────────── @@ -49,6 +50,7 @@ # ── Config ─────────────────────────────────────────────────────────────────── + def load_config() -> dict: config_path = Path("config/config.yaml") if not config_path.exists(): @@ -75,6 +77,7 @@ def load_config() -> dict: # ── Main ───────────────────────────────────────────────────────────────────── + async def post_init(application): """Called after bot starts — boot background tasks.""" cfg = application.bot_data["config"] diff --git a/bot/scheduler.py b/bot/scheduler.py index 6d56173..a29b836 100644 --- a/bot/scheduler.py +++ b/bot/scheduler.py @@ -64,7 +64,6 @@ async def collect_agent_metrics(context): """Pull latest metrics from all online agents and check thresholds.""" import asyncio - cfg = context.bot_data.get("config", {}) agents = context.bot_data.get("agents", {}) admins = cfg.get("bot", {}).get("admin_ids", []) diff --git a/discovery/snmp_scanner.py b/discovery/snmp_scanner.py index c5d3c3d..b300e50 100644 --- a/discovery/snmp_scanner.py +++ b/discovery/snmp_scanner.py @@ -184,7 +184,7 @@ async def get_oid(oid_str): if_in = await get_oid(f"{OID_IF_IN}.1") if_out = await get_oid(f"{OID_IF_OUT}.1") - if_in_str = _bytes_to_human(int(if_in)) if if_in else "N/A" + if_in_str = _bytes_to_human(int(if_in)) if if_in else "N/A" if_out_str = _bytes_to_human(int(if_out)) if if_out else "N/A" # CPU load (UCD-SNMP or HOST-MIB) @@ -206,7 +206,7 @@ async def get_oid(oid_str): pass return { - "name": str(name) if name else ip, + "name": str(name) if name else ip, "description": str(description) if description else "Unknown", "uptime": uptime_str, "if_in": if_in_str, diff --git a/requirements.txt b/requirements.txt index 53e3b49..4168a79 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,9 @@ cryptography==41.0.7 requests==2.31.0 psutil==5.9.7 scapy==2.5.0 -nmap==0.0.1 +# removed: 'nmap' does not exist on PyPI (the correct package is python-nmap, +# pinned on the next line). This phantom pin made 'pip install -r requirements.txt' +# fail outright, which is what actually broke the CI job. python-nmap==0.7.1 ipaddress==1.0.23 humanize==4.9.0 diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..1bc5c63 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,8 @@ +[flake8] +max-line-length = 120 +# E501/W503: long lines + line-break-before-operator are accepted here. +# E221: the codebase deliberately aligns assignment/dict values for readability +# (73 of the original 181 findings). Excluded on purpose. +# This file only works because the workflow no longer passes --ignore, which +# REPLACES flake8's built-in defaults (E24 among them) instead of adding to them. +extend-ignore = E501,W503,E221