Installation

# TypeScript / npm
npm install @carloscortezcloud/nan-graph

# Python / PyPI
pip install nan-graph

First graph (TS)

import { NanGraph, blastRadius, costChain } from '@carloscortezcloud/nan-graph';

const g = new NanGraph()
  .addNode({ id: 'api', type: 'aws.apigateway', attrs: { monthly_cost: 20 } })
  .addNode({ id: 'lambda', type: 'aws.lambda', attrs: { monthly_cost: 5 } })
  .addNode({ id: 'ddb', type: 'aws.dynamodb', attrs: { monthly_cost: 30 } })
  .addEdge({ from: 'api', to: 'lambda', relType: 'routes_to' })
  .addEdge({ from: 'lambda', to: 'ddb', relType: 'reads_writes' });

console.log(blastRadius(g, 'api')); // ['lambda', 'ddb'] — qué se cae si api falla
console.log(costChain(g, 'api'));   // 55 — costo downstream total ($/mes)

Same graph in Python

from nangraph import NanGraph, blast_radius, cost_chain

g = (
    NanGraph()
    .add_node({"id": "api", "type": "aws.apigateway", "attrs": {"monthly_cost": 20}})
    .add_node({"id": "lambda", "type": "aws.lambda", "attrs": {"monthly_cost": 5}})
    .add_node({"id": "ddb", "type": "aws.dynamodb", "attrs": {"monthly_cost": 30}})
    .add_edge("api", "lambda", "routes_to")
    .add_edge("lambda", "ddb", "reads_writes")
)

print(blast_radius(g, "api"))  # ['lambda', 'ddb']
print(cost_chain(g, "api"))    # 55.0

Import from YAML / JSON

dependency-graph.yaml style:

import { fromYaml } from '@carloscortezcloud/nan-graph';
const g = fromYaml(`
nodes:
  sofe-engine: { type: python-library }
  sofe-server: { type: python-api }
edges:
  - { from: sofe-engine, to: sofe-server, relType: bundles }
`);

BYaML v0.3 style (components + relationships):

from nangraph import from_object
g = from_object({
    "components": [{"id": "api", "type": "aws.apigateway", "monthly_cost": 20}],
    "relationships": [{"from": "api", "to": "lambda", "type": "routes_to"}],
})

Next