refactor(pep8): enforce full PEP8 compliance across backend Python codebase

- ruff.toml: select E/W/F/I/N rules, line-length=120, drop legacy ignores
- Auto-fix: sort 82 import blocks (isort), remove 29 unused imports,
  strip 6 trailing-whitespace blank lines in docstrings
- main.py: move setup_logging and settings imports to top (E402)
- errors.py: noqa N818 on DDD exception names (96 call sites, safe)
- intel_service.py: noqa N817 for universal ET alias
- atomic/elastic/sigma import services: move _MAX_UNCOMPRESSED_SIZE and
  _MAX_ENTRIES to module level (N806)
- compliance_import_service.py: move SAMPLE_CONTROLS / CIS_CONTROLS to
  module level; wrap long description strings (N806 + E501)
- snapshot_service.py: move STATUS_ORDER dict to module level (N806)
- sigma_import_service.py: remove dead dedup_key expression (F841)
- threat_actor_import_service.py: remove dead stix_to_actor expression (F841)
- data_source.py, seed_demo.py, campaign_scheduler_service.py,
  lolbas_import_service.py: wrap lines exceeding 120 chars (E501)
- d3fend_import_service.py: per-file E501 ignore (data file with long strings)

All 439 unit tests pass. ruff check app/ → All checks passed!

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kitos
2026-06-09 16:40:14 +02:00
parent 1249391ef0
commit ec26183e2e
85 changed files with 712 additions and 432 deletions
+9 -8
View File
@@ -11,11 +11,10 @@ import os
from fastapi import APIRouter, Cookie, Depends, Request, Response
from fastapi.security import OAuth2PasswordRequestForm
from jose import JWTError, jwt
from sqlalchemy.orm import Session
from jose import jwt, JWTError
from app.auth import create_access_token, blacklist_token, verify_password
from app.auth import blacklist_token, create_access_token, verify_password
from app.config import settings
from app.database import get_db
from app.dependencies.auth import get_current_user
@@ -24,13 +23,15 @@ from app.domain.unit_of_work import UnitOfWork
from app.limiter import limiter
from app.middleware.request_context import resolve_client_ip
from app.models.user import User
from app.services.auth_service import (
_DUMMY_HASH,
change_password as auth_change_password,
)
from app.services.audit_service import log_action
from app.schemas.auth import TokenResponse, UserOut
from app.schemas.user import PasswordChange
from app.services.audit_service import log_action
from app.services.auth_service import (
_DUMMY_HASH,
)
from app.services.auth_service import (
change_password as auth_change_password,
)
router = APIRouter(prefix="/auth", tags=["auth"])
+27 -5
View File
@@ -9,29 +9,51 @@ import uuid
from typing import Optional
from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session
from app.database import get_db
from app.dependencies.auth import get_current_user, require_any_role
from app.domain.unit_of_work import UnitOfWork
from app.models.user import User
from app.services.campaign_service import generate_campaign_from_threat_actor
from app.services.audit_service import log_action
from app.services.campaign_crud_service import (
activate_campaign as crud_activate,
)
from app.services.campaign_crud_service import (
add_test_to_campaign as crud_add_test,
activate_campaign as crud_activate,
)
from app.services.campaign_crud_service import (
complete_campaign as crud_complete,
)
from app.services.campaign_crud_service import (
create_campaign as crud_create,
)
from app.services.campaign_crud_service import (
get_campaign_detail as crud_get_detail,
)
from app.services.campaign_crud_service import (
get_campaign_history as crud_get_history,
)
from app.services.campaign_crud_service import (
get_campaign_progress_data as crud_get_progress,
)
from app.services.campaign_crud_service import (
list_campaigns as crud_list,
)
from app.services.campaign_crud_service import (
remove_test_from_campaign as crud_remove_test,
)
from app.services.campaign_crud_service import (
schedule_campaign as crud_schedule,
)
from app.services.campaign_crud_service import (
serialize_campaign,
)
from app.services.campaign_crud_service import (
update_campaign as crud_update,
)
from app.domain.unit_of_work import UnitOfWork
from app.services.audit_service import log_action
from app.services.campaign_service import generate_campaign_from_threat_actor
from app.services.notification_service import notify_role
logger = logging.getLogger(__name__)
+6 -6
View File
@@ -13,15 +13,15 @@ from sqlalchemy.orm import Session
from app.database import get_db
from app.dependencies.auth import get_current_user, require_role
from app.models.user import User
from app.services.compliance_import_service import (
import_cis_controls_v8_mappings,
import_nist_800_53_mappings,
)
from app.services.compliance_service import (
list_frameworks,
get_framework_status,
build_framework_report_csv,
get_framework_gaps,
)
from app.services.compliance_import_service import (
import_nist_800_53_mappings,
import_cis_controls_v8_mappings,
get_framework_status,
list_frameworks,
)
router = APIRouter(prefix="/compliance", tags=["compliance"])
+5 -3
View File
@@ -10,13 +10,15 @@ from app.database import get_db
from app.dependencies.auth import get_current_user, require_role
from app.models.user import User
from app.services.d3fend_import_service import (
import_d3fend_techniques,
import_d3fend_mappings,
import_d3fend_techniques,
)
from app.services.d3fend_query_service import (
get_defenses_for_attack_technique,
list_d3fend_tactics,
)
from app.services.d3fend_query_service import (
list_defensive_techniques as list_defensive_techniques_svc,
list_d3fend_tactics,
get_defenses_for_attack_technique,
)
logger = logging.getLogger(__name__)
+2 -2
View File
@@ -5,10 +5,11 @@ Provides a centralized panel for managing all external data sources
including sync triggers, enable/disable toggles, and statistics.
"""
from typing import Optional
from fastapi import APIRouter, Depends
from pydantic import BaseModel
from sqlalchemy.orm import Session
from typing import Optional
from app.database import get_db
from app.dependencies.auth import require_role
@@ -23,7 +24,6 @@ from app.services.data_source_service import (
update_source,
)
# ---------------------------------------------------------------------------
# Pydantic schemas for request validation
# ---------------------------------------------------------------------------
+4 -5
View File
@@ -14,17 +14,16 @@ from pydantic import BaseModel
from sqlalchemy.orm import Session
from app.database import get_db
from app.dependencies.auth import get_current_user, require_role, require_any_role
from app.dependencies.auth import get_current_user, require_any_role, require_role
from app.models.user import User
from app.services.detection_rule_service import (
list_rules,
get_rules_for_template,
auto_associate_rules,
get_rules_for_test,
evaluate_rule,
get_rules_for_template,
get_rules_for_test,
list_rules,
)
# ── Pydantic schemas for request validation ────────────────────────────
+3 -3
View File
@@ -28,23 +28,23 @@ from fastapi import APIRouter, Depends, File, Form, Query, Request, UploadFile,
from sqlalchemy.orm import Session
from app.database import get_db
from app.domain.unit_of_work import UnitOfWork
from app.dependencies.auth import get_current_user
from app.domain.unit_of_work import UnitOfWork
from app.limiter import limiter
from app.models.enums import TeamSide
from app.models.evidence import Evidence
from app.models.user import User
from app.schemas.evidence import EvidenceOut
from app.services.audit_service import log_action
from app.services.evidence_service import (
MAX_UPLOAD_SIZE,
get_evidence_or_raise,
get_test_or_raise,
list_evidence_for_test,
MAX_UPLOAD_SIZE,
validate_delete_permission,
validate_file,
validate_upload_permission,
)
from app.limiter import limiter
from app.storage import get_presigned_url, upload_file
router = APIRouter(tags=["evidence"])
+1 -1
View File
@@ -17,7 +17,7 @@ from app.schemas.jira_schema import (
JiraLinkCreate,
JiraLinkOut,
)
from app.services import jira_service, audit_service
from app.services import audit_service, jira_service
logger = logging.getLogger(__name__)
+3 -3
View File
@@ -19,10 +19,10 @@ from app.domain.unit_of_work import UnitOfWork
from app.models.user import User
from app.schemas.notification import NotificationOut, UnreadCountOut
from app.services.notification_service import (
list_notifications,
mark_as_read,
mark_all_as_read,
get_unread_count,
list_notifications,
mark_all_as_read,
mark_as_read,
)
router = APIRouter(prefix="/notifications", tags=["notifications"])
+1 -2
View File
@@ -11,9 +11,8 @@ from app.database import get_db
from app.dependencies.auth import get_current_user
from app.models.user import User
from app.services.operational_metrics_service import (
get_all_operational_metrics,
get_operational_trend,
get_metrics_by_team,
get_operational_trend,
)
router = APIRouter(prefix="/metrics/operational", tags=["operational-metrics"])
+4 -2
View File
@@ -4,7 +4,7 @@ OSINT items (CVEs, advisories, etc.) linked to techniques.
from uuid import UUID
from fastapi import APIRouter, Depends, Query, HTTPException, status
from fastapi import APIRouter, Depends, HTTPException, Query, status
from pydantic import BaseModel
from sqlalchemy.orm import Session
@@ -17,9 +17,11 @@ from app.services.osint_enrichment_service import (
get_osint_items_for_technique,
get_osint_summary,
get_technique_or_raise,
list_osint_items as service_list_osint_items,
mark_osint_reviewed,
)
from app.services.osint_enrichment_service import (
list_osint_items as service_list_osint_items,
)
router = APIRouter(prefix="/osint", tags=["osint"])
+1 -1
View File
@@ -8,8 +8,8 @@ from sqlalchemy.orm import Session
from app.database import get_db
from app.dependencies.auth import get_current_user, require_any_role
from app.models.user import User
from app.limiter import limiter
from app.models.user import User
from app.services import report_generation_service
router = APIRouter(prefix="/reports/generate", tags=["professional-reports"])
+6 -7
View File
@@ -13,17 +13,16 @@ from app.database import get_db
from app.dependencies.auth import get_current_user, require_role
from app.domain.unit_of_work import UnitOfWork
from app.models.user import User
from app.services.scoring_service import (
score_technique_by_mitre_id,
score_actor_by_id,
calculate_tactic_score,
calculate_organization_score,
get_score_history,
)
from app.services.scoring_config_service import (
get_weights_dict,
update_scoring_weights,
)
from app.services.scoring_service import (
calculate_tactic_score,
get_score_history,
score_actor_by_id,
score_technique_by_mitre_id,
)
router = APIRouter(prefix="/scores", tags=["scores"])
+12 -11
View File
@@ -17,18 +17,19 @@ from app.dependencies.auth import get_current_user, require_any_role, require_ro
from app.domain.errors import BusinessRuleViolation
from app.domain.unit_of_work import UnitOfWork
from app.models.user import User
from app.services.snapshot_service import (
create_snapshot,
compare_snapshots,
cleanup_old_snapshots,
get_coverage_evolution,
serialize_snapshot_summary,
list_snapshots as list_snapshots_svc,
get_snapshot_or_raise,
get_snapshot_detail,
delete_snapshot,
)
from app.services.audit_service import log_action
from app.services.snapshot_service import (
compare_snapshots,
create_snapshot,
delete_snapshot,
get_coverage_evolution,
get_snapshot_detail,
get_snapshot_or_raise,
serialize_snapshot_summary,
)
from app.services.snapshot_service import (
list_snapshots as list_snapshots_svc,
)
logger = logging.getLogger(__name__)
+4 -4
View File
@@ -12,12 +12,12 @@ from sqlalchemy.orm import Session
from app.database import get_db
from app.dependencies.auth import require_role
from app.models.user import User
from app.services.mitre_sync_service import sync_mitre
from app.services.intel_service import scan_intel
from app.services.atomic_import_service import import_atomic_red_team
from app.jobs.mitre_sync_job import scheduler
from app.limiter import limiter
from app.models.user import User
from app.services.atomic_import_service import import_atomic_red_team
from app.services.intel_service import scan_intel
from app.services.mitre_sync_service import sync_mitre
logger = logging.getLogger(__name__)
+2 -2
View File
@@ -9,11 +9,11 @@ from fastapi import APIRouter, Depends, Query, status
from sqlalchemy.orm import Session
from app.database import get_db
from app.dependencies.auth import get_current_user, require_role, require_any_role
from app.dependencies.auth import get_current_user, require_any_role, require_role
from app.dependencies.repositories import get_technique_repository
from app.domain.entities.technique import TechniqueEntity
from app.domain.errors import DuplicateEntityError, EntityNotFoundError
from app.domain.enums import TechniqueStatus
from app.domain.errors import DuplicateEntityError, EntityNotFoundError
from app.domain.unit_of_work import UnitOfWork
from app.infrastructure.persistence.repositories.sa_technique_repository import (
SATechniqueRepository,
+10 -2
View File
@@ -40,13 +40,21 @@ from app.schemas.test_template import (
from app.services.audit_service import log_action
from app.services.test_template_service import (
bulk_activate,
create_template as create_template_svc,
get_template_or_raise,
get_template_stats,
get_templates_by_technique as templates_by_technique,
list_templates,
soft_delete_template,
)
from app.services.test_template_service import (
create_template as create_template_svc,
)
from app.services.test_template_service import (
get_templates_by_technique as templates_by_technique,
)
from app.services.test_template_service import (
toggle_template_active as toggle_template_active_svc,
)
from app.services.test_template_service import (
update_template as update_template_svc,
)
+48 -13
View File
@@ -26,49 +26,84 @@ from sqlalchemy.orm import Session
from app.database import get_db
from app.dependencies.auth import get_current_user, require_any_role, require_role
from app.domain.enums import DataClassification
from app.domain.unit_of_work import UnitOfWork
from app.limiter import limiter
from app.models.enums import TestState
from app.models.user import User
from app.schemas.test import (
TestBlueUpdate,
TestBlueValidate,
TestClassificationUpdate,
TestCreate,
TestOut,
TestUpdate,
TestRedUpdate,
TestBlueUpdate,
TestRedValidate,
TestBlueValidate,
TestRemediationUpdate,
TestClassificationUpdate,
TestUpdate,
)
from app.schemas.test_template import TestTemplateInstantiate
from app.domain.unit_of_work import UnitOfWork
from app.services.audit_service import log_action
from app.services.status_service import recalculate_technique_status
from app.services.test_crud_service import (
create_test as crud_create_test,
)
from app.services.test_crud_service import (
create_test_from_template as crud_create_from_template,
)
from app.services.test_crud_service import (
get_test_detail as crud_get_test_detail,
)
from app.services.test_crud_service import (
get_test_or_raise as crud_get_test_or_raise,
)
from app.services.test_crud_service import (
get_test_timeline as crud_get_test_timeline,
)
from app.services.test_crud_service import (
get_test_with_technique as crud_get_test_with_technique,
)
from app.services.test_crud_service import (
list_tests as crud_list_tests,
)
from app.services.test_crud_service import (
update_test as crud_update_test,
)
from app.services.test_crud_service import (
update_test_blue as crud_update_test_blue,
)
from app.services.test_crud_service import (
update_test_red as crud_update_test_red,
)
from app.services.test_workflow_service import (
start_execution as wf_start_execution,
submit_red_evidence as wf_submit_red,
submit_blue_evidence as wf_submit_blue,
validate_as_red_lead as wf_validate_red,
validate_as_blue_lead as wf_validate_blue,
reopen_test as wf_reopen,
handle_remediation_completed as wf_handle_remediation,
get_retest_chain as wf_get_retest_chain,
)
from app.services.test_workflow_service import (
handle_remediation_completed as wf_handle_remediation,
)
from app.services.test_workflow_service import (
pause_timer as wf_pause_timer,
)
from app.services.test_workflow_service import (
reopen_test as wf_reopen,
)
from app.services.test_workflow_service import (
resume_timer as wf_resume_timer,
)
from app.services.test_workflow_service import (
start_execution as wf_start_execution,
)
from app.services.test_workflow_service import (
submit_blue_evidence as wf_submit_blue,
)
from app.services.test_workflow_service import (
submit_red_evidence as wf_submit_red,
)
from app.services.test_workflow_service import (
validate_as_blue_lead as wf_validate_blue,
)
from app.services.test_workflow_service import (
validate_as_red_lead as wf_validate_red,
)
router = APIRouter(prefix="/tests", tags=["tests"])
+1 -1
View File
@@ -9,7 +9,7 @@ from app.database import get_db
from app.dependencies.auth import require_role
from app.domain.unit_of_work import UnitOfWork
from app.models.user import User
from app.schemas.user import UserCreate, UserUpdate, UserOut
from app.schemas.user import UserCreate, UserOut, UserUpdate
from app.services.audit_service import log_action
from app.services.user_service import (
create_user,
+1 -1
View File
@@ -4,7 +4,7 @@ from datetime import datetime
from typing import Optional
from uuid import UUID
from fastapi import APIRouter, Depends, Query
from fastapi import APIRouter, Depends
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session