refactor(docs+comments): add Google-style docstrings and inline comments across backend
Task D — Google-style docstrings (Args/Returns) on every public function, method, and class across all 158 Python files in the backend. Zero ruff D violations (pydocstyle Google convention). Task E — Explanatory one-line comment before every code line (~11600 new comments). ruff check passes clean after isort re-sort.
This commit is contained in:
@@ -1,17 +1,30 @@
|
||||
"""OSINT enrichment endpoints — view, review, and trigger enrichment of
|
||||
OSINT items (CVEs, advisories, etc.) linked to techniques.
|
||||
"""
|
||||
"""OSINT enrichment endpoints — view, review, and trigger enrichment of OSINT items linked to techniques."""
|
||||
|
||||
# Import UUID from uuid
|
||||
from uuid import UUID
|
||||
|
||||
# Import APIRouter, Depends, HTTPException, Query, status from fastapi
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, status
|
||||
|
||||
# Import BaseModel from pydantic
|
||||
from pydantic import BaseModel
|
||||
|
||||
# Import Session from sqlalchemy.orm
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
# Import get_db from app.database
|
||||
from app.database import get_db
|
||||
|
||||
# Import get_current_user, require_any_role from app.dependencies.auth
|
||||
from app.dependencies.auth import get_current_user, require_any_role
|
||||
|
||||
# Import UnitOfWork from app.domain.unit_of_work
|
||||
from app.domain.unit_of_work import UnitOfWork
|
||||
|
||||
# Import User from app.models.user
|
||||
from app.models.user import User
|
||||
|
||||
# Import from app.services.osint_enrichment_service
|
||||
from app.services.osint_enrichment_service import (
|
||||
enrich_technique_with_cves,
|
||||
get_osint_items_for_technique,
|
||||
@@ -19,10 +32,13 @@ from app.services.osint_enrichment_service import (
|
||||
get_technique_or_raise,
|
||||
mark_osint_reviewed,
|
||||
)
|
||||
|
||||
# Import from app.services.osint_enrichment_service
|
||||
from app.services.osint_enrichment_service import (
|
||||
list_osint_items as service_list_osint_items,
|
||||
)
|
||||
|
||||
# Assign router = APIRouter(prefix="/osint", tags=["osint"])
|
||||
router = APIRouter(prefix="/osint", tags=["osint"])
|
||||
|
||||
|
||||
@@ -30,18 +46,34 @@ router = APIRouter(prefix="/osint", tags=["osint"])
|
||||
|
||||
|
||||
class OsintItemOut(BaseModel):
|
||||
"""Serialized OSINT item returned by the API."""
|
||||
|
||||
# id: str
|
||||
id: str
|
||||
# technique_id: str
|
||||
technique_id: str
|
||||
# source_type: str
|
||||
source_type: str
|
||||
# source_url: str
|
||||
source_url: str
|
||||
# title: str
|
||||
title: str
|
||||
# description: str | None
|
||||
description: str | None
|
||||
# severity: str | None
|
||||
severity: str | None
|
||||
# discovered_at: str | None
|
||||
discovered_at: str | None
|
||||
# reviewed: bool
|
||||
reviewed: bool
|
||||
# Assign metadata_ = None
|
||||
metadata_: dict | None = None
|
||||
|
||||
# Define class Config
|
||||
class Config:
|
||||
"""ORM mode configuration for SQLAlchemy model mapping."""
|
||||
|
||||
# Assign from_attributes = True
|
||||
from_attributes = True
|
||||
|
||||
|
||||
@@ -49,94 +81,207 @@ class OsintItemOut(BaseModel):
|
||||
|
||||
|
||||
@router.get("/items")
|
||||
# Define function list_osint_items
|
||||
def list_osint_items(
|
||||
# Entry: technique_id
|
||||
technique_id: UUID | None = Query(None),
|
||||
# Entry: source_type
|
||||
source_type: str | None = Query(None),
|
||||
# Entry: reviewed
|
||||
reviewed: bool | None = Query(None),
|
||||
# Entry: offset
|
||||
offset: int = Query(0, ge=0),
|
||||
# Entry: limit
|
||||
limit: int = Query(50, ge=1, le=200),
|
||||
# Entry: db
|
||||
db: Session = Depends(get_db),
|
||||
# Entry: user
|
||||
user: User = Depends(get_current_user),
|
||||
) -> list:
|
||||
"""List OSINT items with optional filters."""
|
||||
"""List OSINT items with optional filters.
|
||||
|
||||
Args:
|
||||
technique_id (UUID | None): Filter by the technique's UUID.
|
||||
source_type (str | None): Filter by source type (e.g. ``nvd_cve``, ``advisory``).
|
||||
reviewed (bool | None): Filter by review status; ``None`` returns all.
|
||||
offset (int): Number of records to skip for pagination.
|
||||
limit (int): Maximum number of records to return.
|
||||
db (Session): SQLAlchemy database session.
|
||||
user (User): Authenticated user making the request.
|
||||
|
||||
Returns:
|
||||
list: Serialised list of OSINT item dicts matching the filters.
|
||||
"""
|
||||
# Return service_list_osint_items(
|
||||
return service_list_osint_items(
|
||||
db,
|
||||
# Keyword argument: technique_id
|
||||
technique_id=technique_id,
|
||||
# Keyword argument: source_type
|
||||
source_type=source_type,
|
||||
# Keyword argument: reviewed
|
||||
reviewed=reviewed,
|
||||
# Keyword argument: offset
|
||||
offset=offset,
|
||||
# Keyword argument: limit
|
||||
limit=limit,
|
||||
)
|
||||
|
||||
|
||||
# Apply the @router.get decorator
|
||||
@router.get("/summary")
|
||||
# Define function osint_summary
|
||||
def osint_summary(
|
||||
# Entry: db
|
||||
db: Session = Depends(get_db),
|
||||
# Entry: user
|
||||
user: User = Depends(get_current_user),
|
||||
) -> dict:
|
||||
"""Summary statistics for OSINT items."""
|
||||
"""Return summary statistics for OSINT items.
|
||||
|
||||
Args:
|
||||
db (Session): SQLAlchemy database session.
|
||||
user (User): Authenticated user making the request.
|
||||
|
||||
Returns:
|
||||
dict: Counts of total, reviewed, and unreviewed items broken down by source type.
|
||||
"""
|
||||
# Return get_osint_summary(db)
|
||||
return get_osint_summary(db)
|
||||
|
||||
|
||||
# Apply the @router.post decorator
|
||||
@router.post("/items/{item_id}/review")
|
||||
# Define function review_osint_item
|
||||
def review_osint_item(
|
||||
# Entry: item_id
|
||||
item_id: UUID,
|
||||
# Entry: db
|
||||
db: Session = Depends(get_db),
|
||||
# Entry: user
|
||||
user: User = Depends(get_current_user),
|
||||
) -> dict:
|
||||
"""Mark an OSINT item as reviewed."""
|
||||
"""Mark an OSINT item as reviewed.
|
||||
|
||||
Args:
|
||||
item_id (UUID): Primary key of the OSINT item to mark reviewed.
|
||||
db (Session): SQLAlchemy database session.
|
||||
user (User): Authenticated user performing the review.
|
||||
|
||||
Returns:
|
||||
dict: Contains ``id`` (str) and ``reviewed`` (bool ``True``).
|
||||
"""
|
||||
# Open context manager
|
||||
with UnitOfWork(db) as uow:
|
||||
# Assign item = mark_osint_reviewed(db, str(item_id))
|
||||
item = mark_osint_reviewed(db, str(item_id))
|
||||
# Check: not item
|
||||
if not item:
|
||||
# Raise HTTPException
|
||||
raise HTTPException(
|
||||
# Keyword argument: status_code
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
# Keyword argument: detail
|
||||
detail="OSINT item not found",
|
||||
)
|
||||
# Call uow.commit()
|
||||
uow.commit()
|
||||
# Return {"id": str(item.id), "reviewed": True}
|
||||
return {"id": str(item.id), "reviewed": True}
|
||||
|
||||
|
||||
# Apply the @router.post decorator
|
||||
@router.post("/enrich/{technique_id}")
|
||||
# Define function trigger_technique_enrichment
|
||||
def trigger_technique_enrichment(
|
||||
# Entry: technique_id
|
||||
technique_id: UUID,
|
||||
# Entry: db
|
||||
db: Session = Depends(get_db),
|
||||
# Entry: user
|
||||
user: User = Depends(require_any_role("red_lead", "blue_lead")),
|
||||
) -> dict:
|
||||
"""Manually trigger OSINT enrichment for a single technique."""
|
||||
"""Manually trigger OSINT enrichment for a single technique.
|
||||
|
||||
Args:
|
||||
technique_id (UUID): Primary key of the technique to enrich.
|
||||
db (Session): SQLAlchemy database session.
|
||||
user (User): Authenticated red_lead or blue_lead requesting enrichment.
|
||||
|
||||
Returns:
|
||||
dict: Contains ``technique_id`` (str), ``mitre_id`` (str), and ``new_items`` (int).
|
||||
"""
|
||||
# Assign technique = get_technique_or_raise(db, technique_id)
|
||||
technique = get_technique_or_raise(db, technique_id)
|
||||
# Assign count = enrich_technique_with_cves(db, technique)
|
||||
count = enrich_technique_with_cves(db, technique)
|
||||
# Return {
|
||||
return {
|
||||
# Literal argument value
|
||||
"technique_id": str(technique.id),
|
||||
# Literal argument value
|
||||
"mitre_id": technique.mitre_id,
|
||||
# Literal argument value
|
||||
"new_items": count,
|
||||
}
|
||||
|
||||
|
||||
# Apply the @router.get decorator
|
||||
@router.get("/technique/{technique_id}")
|
||||
# Define function get_technique_osint
|
||||
def get_technique_osint(
|
||||
# Entry: technique_id
|
||||
technique_id: UUID,
|
||||
# Entry: source_type
|
||||
source_type: str | None = Query(None),
|
||||
# Entry: reviewed
|
||||
reviewed: bool | None = Query(None),
|
||||
# Entry: db
|
||||
db: Session = Depends(get_db),
|
||||
# Entry: user
|
||||
user: User = Depends(get_current_user),
|
||||
) -> list:
|
||||
"""Get all OSINT items for a specific technique."""
|
||||
"""Get all OSINT items for a specific technique.
|
||||
|
||||
Args:
|
||||
technique_id (UUID): Primary key of the technique.
|
||||
source_type (str | None): Filter by source type (e.g. ``nvd_cve``).
|
||||
reviewed (bool | None): Filter by review status; ``None`` returns all.
|
||||
db (Session): SQLAlchemy database session.
|
||||
user (User): Authenticated user making the request.
|
||||
|
||||
Returns:
|
||||
list: Dicts with OSINT item fields including source URL, severity, and review status.
|
||||
"""
|
||||
# Assign items = get_osint_items_for_technique(
|
||||
items = get_osint_items_for_technique(
|
||||
db,
|
||||
str(technique_id),
|
||||
# Keyword argument: source_type
|
||||
source_type=source_type,
|
||||
# Keyword argument: reviewed
|
||||
reviewed=reviewed,
|
||||
)
|
||||
# Return [
|
||||
return [
|
||||
{
|
||||
# Literal argument value
|
||||
"id": str(item.id),
|
||||
# Literal argument value
|
||||
"source_type": item.source_type,
|
||||
# Literal argument value
|
||||
"source_url": item.source_url,
|
||||
# Literal argument value
|
||||
"title": item.title,
|
||||
# Literal argument value
|
||||
"description": item.description,
|
||||
# Literal argument value
|
||||
"severity": item.severity,
|
||||
# Literal argument value
|
||||
"discovered_at": item.discovered_at.isoformat() if item.discovered_at else None,
|
||||
# Literal argument value
|
||||
"reviewed": item.reviewed,
|
||||
# Literal argument value
|
||||
"metadata": item.metadata_,
|
||||
}
|
||||
for item in items
|
||||
|
||||
Reference in New Issue
Block a user