Skip to content

feat(scc): SCC analysis — closes #1#15

Open
galigaribaldi wants to merge 3 commits into
DEVfrom
feature/scc-analysis
Open

feat(scc): SCC analysis — closes #1#15
galigaribaldi wants to merge 3 commits into
DEVfrom
feature/scc-analysis

Conversation

@galigaribaldi

@galigaribaldi galigaribaldi commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • Nuevo módulo scc_analysis/ con motor Tarjan, diagnósticos por sistema y orquestador
  • Integración automática post-build del grafo(SCC_CACHE)
  • Endpoint GET /api/v1/network/topological/scc-analysis
  • Resultado: componente gigante = 95.02% → Fase 3 desbloqueada (T y B)

Test plan

Summary by Sourcery

Add SCC-based topological connectivity analysis for the network graph and expose it via a new API endpoint, caching results alongside the built graph.

New Features:

  • Introduce an SCC analysis module with engine, diagnostics, and orchestrator to evaluate strongly connected components and phase 3 readiness.
  • Expose a new HTTP endpoint to retrieve SCC analysis reports for a given graph configuration, including phase_3 readiness and fragmentation details.

Enhancements:

  • Augment the graph-building dependency to compute and cache SCC diagnostics and the giant component immediately after graph construction for reuse by downstream features.

…d scc_analysis module: engine (Tarjan), diagnostics (fragmentation/isolation), orchestrator

\n - Integrate SCC into graph post-build flow with SCC_CACHE in dependencies.py
\n - Add GET /api/v1/network/topological/scc-analysis endpoint
\n - Result: giant component 95.02% (10,561/11,115 nodes) → Phase 3 ready
@sourcery-ai

sourcery-ai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds a strongly connected components (SCC) analysis pipeline (Tarjan-based) that runs automatically after graph build, caches the results, and exposes them via a new API endpoint to determine Phase 3 readiness based on the size of the giant component.

Sequence diagram for SCC analysis API endpoint and caching

sequenceDiagram
    actor Client
    participant API as FastAPI_app
    participant Dep as get_or_build_graph
    participant GraphBuilder as VFTGraphBuilder
    participant Orchestrator as SCCOrchestrator
    participant SCCCache as SCC_CACHE
    participant ReportDep as get_scc_report

    Client->>API: GET /api/v1/network/topological/scc-analysis
    API->>Dep: get_or_build_graph(mode, tolerance_m)
    alt Graph_not_in_GRAPH_CACHE
        Dep->>GraphBuilder: build_graph(mode, tolerance_m)
        GraphBuilder-->>Dep: G
        Dep->>Orchestrator: SCCOrchestrator(G)
        Orchestrator->>Orchestrator: analyze()
        Orchestrator-->>Dep: scc_report, giant_component
        Dep->>SCCCache: store {report, giant_component}
        Dep-->>API: G
    else Graph_in_GRAPH_CACHE
        Dep-->>API: G
    end
    API->>ReportDep: get_scc_report(mode, tolerance_m)
    ReportDep->>SCCCache: get(cache_key)
    SCCCache-->>ReportDep: report | None
    ReportDep-->>API: report
    alt report is None
        API-->>Client: HTTP 500 (SCC analysis no disponible)
    else report available
        API-->>Client: JSON {status, parametros, data}
    end
Loading

File-Level Changes

Change Details Files
Expose SCC connectivity diagnostics via a new HTTP endpoint.
  • Add FastAPI route GET /api/v1/network/topological/scc-analysis with query params mode and tolerance_m.
  • Within the handler, ensure the graph is built (or loaded from cache) and retrieve an SCC report from cache.
  • Return a structured JSON payload with parameters, SCC statistics, and phase_3 readiness, with defensive HTTPException handling.
src/api/main.py
Extend dependency layer to compute and cache SCC analysis right after graph construction.
  • Introduce an in-memory SCC_CACHE keyed by mode and tolerance to store SCC reports and giant component subgraphs.
  • After building the graph in get_or_build_graph, instantiate SCCOrchestrator to compute the SCC report and giant component, and store them in SCC_CACHE.
  • Expose helper functions get_scc_report and get_giant_component to access cached SCC results from API handlers.
src/api/dependencies.py
Implement SCC analysis module with engine, diagnostics, and orchestration layers.
  • Create SCCOrchestrator class that validates input graph, runs Tarjan-based SCC computation once, assembles a full diagnostic report, and decides if the network is Phase 3 ready using a configurable threshold.
  • Implement pure engine functions to compute and sort SCCs, extract the giant component as an independent subgraph, and compute its basic metrics.
  • Provide diagnostics helpers to aggregate fragmentation by transport system and summarize the largest non-giant components, excluding trace-only nodes.
  • Expose SCCOrchestrator through a package init to simplify imports in higher layers.
src/core/algorithms/topologicalIndicators/scc_analysis/orchestator.py
src/core/algorithms/topologicalIndicators/scc_analysis/diagnostics.py
src/core/algorithms/topologicalIndicators/scc_analysis/engine.py
src/core/algorithms/topologicalIndicators/scc_analysis/__init__.py

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • In src/api/dependencies.py, get_giant_component computes the cache_key but never returns anything from SCC_CACHE, so the helper is currently unusable; you likely want to mirror get_scc_report and return SCC_CACHE.get(cache_key, {}).get("giant_component").
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `src/api/dependencies.py`, `get_giant_component` computes the `cache_key` but never returns anything from `SCC_CACHE`, so the helper is currently unusable; you likely want to mirror `get_scc_report` and return `SCC_CACHE.get(cache_key, {}).get("giant_component")`.

## Individual Comments

### Comment 1
<location path="src/api/dependencies.py" line_range="41-44" />
<code_context>
\ No newline at end of file
+
+    # --- SCC: diagnóstico post-build ---
+    analyzer = SCCOrchestrator(G)
+    scc_report = analyzer.analyze()
+    giant = analyzer.get_giant_component()
+    SCC_CACHE[cache_key] = {"report": scc_report, "giant_component": giant}
+
+    return G
</code_context>
<issue_to_address>
**suggestion (performance):** SCC analysis runs synchronously in the event loop thread, which can block the API on large graphs.

Graph construction is already offloaded with `asyncio.to_thread`, but `SCCOrchestrator.analyze()` and `get_giant_component()` still run on the event loop. For large graphs, Tarjan + metric computation can block request handling. Please move the SCC work into the existing `to_thread` call, or wrap the SCC analysis in its own `asyncio.to_thread` to avoid blocking the event loop.

Suggested implementation:

```python
    # --- SCC: diagnóstico post-build ---
    def _run_scc_analysis(graph):
        analyzer = SCCOrchestrator(graph)
        report = analyzer.analyze()
        giant = analyzer.get_giant_component()
        return {"report": report, "giant_component": giant}

    scc_result = await asyncio.to_thread(_run_scc_analysis, G)
    SCC_CACHE[cache_key] = scc_result

    return G

```

- This change assumes `asyncio` is already imported in `src/api/dependencies.py`. If not, add `import asyncio` at the top of the file.
- If there is a shared pattern or helper for CPU-bound work (e.g. a central `run_in_threadpool` wrapper), you may want to replace `asyncio.to_thread` with that to keep consistency with the rest of the codebase.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/api/dependencies.py
Comment on lines +41 to +44
analyzer = SCCOrchestrator(G)
scc_report = analyzer.analyze()
giant = analyzer.get_giant_component()
SCC_CACHE[cache_key] = {"report": scc_report, "giant_component": giant}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (performance): SCC analysis runs synchronously in the event loop thread, which can block the API on large graphs.

Graph construction is already offloaded with asyncio.to_thread, but SCCOrchestrator.analyze() and get_giant_component() still run on the event loop. For large graphs, Tarjan + metric computation can block request handling. Please move the SCC work into the existing to_thread call, or wrap the SCC analysis in its own asyncio.to_thread to avoid blocking the event loop.

Suggested implementation:

    # --- SCC: diagnóstico post-build ---
    def _run_scc_analysis(graph):
        analyzer = SCCOrchestrator(graph)
        report = analyzer.analyze()
        giant = analyzer.get_giant_component()
        return {"report": report, "giant_component": giant}

    scc_result = await asyncio.to_thread(_run_scc_analysis, G)
    SCC_CACHE[cache_key] = scc_result

    return G
  • This change assumes asyncio is already imported in src/api/dependencies.py. If not, add import asyncio at the top of the file.
  • If there is a shared pattern or helper for CPU-bound work (e.g. a central run_in_threadpool wrapper), you may want to replace asyncio.to_thread with that to keep consistency with the rest of the codebase.

- Restructure topologicalIndicators/ into topological/, spatial/, demand/
\n- Add @phase: header to all indicator files for roadmap traceability
\n- Update 13 imports across API layer (main.py, dependencies.py, geo_layers.py)
\n- Update 4 imports in notebooks (02, 03, 04)
\n- Rewrite Description.md with new architecture and domain taxonomy
\n- Add demand/ placeholder for future Apimetro Plutarco indicators
- Restructure topologicalIndicators/ into topological/, spatial/, demand/
\n- Add @phase: header to all indicator files for roadmap traceability
\n- Update 13 imports across API layer (main.py, dependencies.py, geo_layers.py)
\n- Update 4 imports in notebooks (02, 03, 04)
\n- Rewrite Description.md with new architecture and domain taxonomy
\n- Add demand/ placeholder for future Apimetro Plutarco indicators
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant