Working with Networks
Advanced network operations and management techniques.
Network Formats
CX2 Format (Recommended)
CX2 is the modern network format used by NDEx v3 API:
// Upload CX2 network
const cx2Network = [
{
"CXVersion": "2.0",
"hasFragments": false
},
{
"metaData": [
{"name": "nodes", "elementCount": 3},
{"name": "edges", "elementCount": 2},
{"name": "networkAttributes", "elementCount": 1}
]
},
{
"networkAttributes": [
{"n": "name", "v": "My Pathway Network"}
]
},
{
"nodes": [
{"id": 0, "v": {"n": "EGFR", "r": "protein"}},
{"id": 1, "v": {"n": "TP53", "r": "protein"}},
{"id": 2, "v": {"n": "KRAS", "r": "protein"}}
]
},
{
"edges": [
{"id": 0, "s": 0, "t": 1, "v": {"i": "phosphorylates"}},
{"id": 1, "s": 1, "t": 2, "v": {"i": "regulates"}}
]
},
{
"status": [
{"success": true}
]
}
];
import { Visibility } from '@js4cytoscape/ndex-client';
const result = await client.networks.createNetworkFromRawCX2(cx2Network, { visibility: Visibility.PUBLIC });
Legacy CX Format
For compatibility with older systems:
// Upload CX1 network
const cxNetwork = [
{"numberVerification": [{"longNumber": 283213721732712}]},
{"metaData": [
{"name": "nodes", "elementCount": 2},
{"name": "edges", "elementCount": 1}
]},
{"nodes": [
{"@id": 0, "n": "Node1", "r": "protein"},
{"@id": 1, "n": "Node2", "r": "protein"}
]},
{"edges": [
{"@id": 0, "s": 0, "t": 1, "i": "interacts"}
]},
{"status": [
{"success": true}
]}
];
const result = await client.networks.createNetworkFromRawCX2(cxNetwork);
Network Metadata
Get Network Aspects
const networkUUID = 'your-network-uuid';
// Get CX2 metadata
const cx2Meta = await client.networks.getCX2MetaData(networkUUID);
console.log('Available aspects:', cx2Meta.map(m => m.name));
// Get specific aspect data
const nodes = await client.networks.getAspectElements(networkUUID, 'nodes', 100);
const edges = await client.networks.getAspectElements(networkUUID, 'edges', 100);
Network Attributes
// Get network attributes
const attributes = await client.networks.getAspectElements(networkUUID, 'networkAttributes');
console.log('Network attributes:', attributes);
// Common network attributes
attributes.forEach(attr => {
switch(attr.n) {
case 'name':
console.log('Network name:', attr.v);
break;
case 'description':
console.log('Description:', attr.v);
break;
case 'version':
console.log('Version:', attr.v);
break;
}
});
Network Queries
Neighborhood Queries
Find nodes and their neighbors:
const networkUUID = 'your-network-uuid';
// Find neighbors of specific proteins
const neighborhoodResult = await client.networks.neighborhoodQuery(
networkUUID,
'EGFR TP53', // search terms
false, // don't save result
{
searchDepth: 2, // 2 hops from search terms
edgeLimit: 100, // max edges to return
directOnly: false // include indirect connections
},
true // return CX2 format
);
console.log('Neighborhood network:', neighborhoodResult);
Interconnect Queries
Find paths between specific nodes:
// Find connections between proteins
const interconnectResult = await client.networks.interConnectQuery(
networkUUID,
'EGFR KRAS', // find paths between these
false, // don't save result
{
edgeLimit: 50,
nodeIds: [0, 2] // specific node IDs if known
},
true // return CX2 format
);
Node Attribute Queries
Query nodes by attributes:
// Find nodes with specific attributes
const nodeResults = await client.getAttributesOfSelectedNodes(
networkUUID,
{
ids: [0, 1, 2], // node IDs
attributeNames: ['name', 'type', 'expression']
}
);
console.log('Node attributes:', nodeResults);
Edge Filtering
Filter edges by attributes:
// Get edges with specific interaction types
const filteredEdges = await client.getFilteredEdges(
networkUUID,
'interaction', // column name
'phosphorylates', // value to search for
'EQUAL', // operator
50, // limit
'ASC', // order
'CX2' // format
);
Batch Operations
Multiple Network Summaries
const networkUUIDs = [
'uuid1',
'uuid2',
'uuid3'
];
// Get summaries in batch (more efficient)
const summaries = await client.getNetworkSummariesV3ByUUIDs(
networkUUIDs,
null, // no access key
'FULL' // full format
);
summaries.forEach(summary => {
console.log(`${summary.name}: ${summary.nodeCount} nodes, ${summary.edgeCount} edges`);
});
Bulk Network Operations
// Move multiple networks to a folder
const networkIds = ['uuid1', 'uuid2', 'uuid3'];
const folderId = 'target-folder-uuid';
await client.moveNetworks(networkIds, folderId);
// Set visibility for multiple networks
const files = {
'uuid1': 'NETWORK',
'uuid2': 'NETWORK',
'uuid3': 'NETWORK'
};
// Visibility options: Visibility.PUBLIC, Visibility.PRIVATE, or Visibility.UNLISTED
await client.setNetworksVisibility(files, Visibility.PUBLIC);
Network Visibility
Networks can have three visibility levels:
- PUBLIC: Anyone can discover and view the network
- PRIVATE: Only the owner and specifically invited users can access
- UNLISTED: Anyone with the direct link can view, but not discoverable in search
// Example: Create network with specific visibility
const result = await client.networks.createNetworkFromRawCX2(cx2Data, {
visibility: Visibility.UNLISTED, // or Visibility.PUBLIC or Visibility.PRIVATE
folderId: 'optional-folder-uuid'
});
Network Permissions
Check Permissions
Permission levels available:
- READ: View and download network content
- WRITE: All READ permissions + modify network content and metadata
- ADMIN: All WRITE permissions + delete network and manage user permissions
const networkUUIDs = ['uuid1', 'uuid2'];
const permissions = await client.getNetworkPermissionsByUUIDs(networkUUIDs);
permissions.forEach(perm => {
console.log(`Network ${perm.networkUUID}: ${perm.permission}`); // 'READ', 'WRITE', or 'ADMIN'
});
Access Keys
const networkUUID = 'your-network-uuid';
// Get current access key
const accessKey = await client.getAccessKey(networkUUID);
console.log('Access key:', accessKey);
// Generate new access key
await client.updateAccessKey(networkUUID, 'generate');
// Disable access key
await client.updateAccessKey(networkUUID, 'delete');
Advanced Features
DOI Management
// Request DOI for network
const doiResult = await client.getNetworkDOI(
networkUUID,
'your-key',
'your-email@example.com'
);
// Cancel DOI request
await client.cancelDOIRequest(networkUUID);
Layout Updates
// Update node positions
const nodePositions = [
{ node: 0, x: 100.5, y: 200.0 },
{ node: 1, x: 150.0, y: 250.5 },
{ node: 2, x: 200.5, y: 300.0 }
];
await client.updateCartesianLayoutAspect(networkUUID, nodePositions);
Random Sampling
// Get random edges for large network analysis
const randomEdges = await client.getRandomEdges(
networkUUID,
100, // sample size
accessKey // optional access key
);
console.log('Random edge sample:', randomEdges);
Error Handling Best Practices
import { NDExServerError, NDExError } from '@js4cytoscape/ndex-client';
async function robustNetworkOperation(networkUUID: string) {
const maxRetries = 3;
let retryCount = 0;
while (retryCount < maxRetries) {
try {
const result = await client.networks.getRawCX2Network(networkUUID);
return result;
} catch (error) {
retryCount++;
if (error instanceof NDExError && error.statusCode === 429) {
// Rate limit - wait and retry
console.log(`Rate limited, waiting... (attempt ${retryCount})`);
await new Promise(resolve => setTimeout(resolve, 1000 * retryCount));
} else if (error instanceof NDExServerError) {
// Server unavailable - wait longer
console.log(`Server unavailable (${error.errorCode}), waiting... (attempt ${retryCount})`);
await new Promise(resolve => setTimeout(resolve, 5000));
} else {
// Other errors - don't retry
throw error;
}
}
}
throw new Error(`Failed after ${maxRetries} retries`);
}
Performance Tips
- Use Batch Operations: When working with multiple networks, use batch APIs
- Limit Result Sets: Always specify limits for large queries
- Cache Network Summaries: Summary data changes infrequently
- Use Appropriate Formats: CX2 for modern apps, CX1 for legacy compatibility
- Implement Retry Logic: Handle rate limiting and temporary failures
Next Steps
- File Operations → - Manage network files and folders
- Workspace Workflows → - Organize networks in workspaces
- Advanced Patterns → - Complex integration patterns