#!/usr/bin/env python3 """ Azure Interactive Architecture Diagram Generator v3 Generates interactive HTML diagrams with Azure official icons (Base64 inline). """ import json from datetime import datetime from icons import get_icon_data_uri _HAS_OFFICIAL_ICONS = True # Azure service icons: SVG, colors + official icon key mapping # icon: 48x48 viewBox SVG path (fallback) # azure_icon_key: key in icons.py (official Azure icon) SERVICE_ICONS = { "openai": { "icon_svg": 'AI', "color": "#0078D4", "bg": "#E8F4FD", "category": "AI", "azure_icon_key": "azure_openai" }, "ai_foundry": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "AI", "azure_icon_key": "azure_openai" }, "ai_hub": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "AI", "azure_icon_key": "machine_learning" }, "search": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "AI", "azure_icon_key": "cognitive_search" }, "ai_search": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "AI", "azure_icon_key": "cognitive_search" }, "aml": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "AI", "azure_icon_key": "machine_learning" }, "storage": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Data", "azure_icon_key": "storage_accounts" }, "adls": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Data", "azure_icon_key": "data_lake_storage_gen1" }, "fabric": { "icon_svg": 'F', "color": "#E8740C", "bg": "#FEF3E8", "category": "Data", "azure_icon_key": "managed_service_fabric" }, "synapse": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Data", "azure_icon_key": "azure_synapse_analytics" }, "adf": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Data", "azure_icon_key": "data_factory" }, "data_factory": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Data", "azure_icon_key": "data_factory" }, "keyvault": { "icon_svg": '', "color": "#E8A000", "bg": "#FEF7E0", "category": "Security", "azure_icon_key": "key_vaults" }, "kv": { "icon_svg": '', "color": "#E8A000", "bg": "#FEF7E0", "category": "Security", "azure_icon_key": "key_vaults" }, "vnet": { "icon_svg": '', "color": "#5C2D91", "bg": "#F3EEF9", "category": "Network", "azure_icon_key": "virtual_networks" }, "pe": { "icon_svg": '', "color": "#5C2D91", "bg": "#F3EEF9", "category": "Network", "azure_icon_key": "private_endpoints" }, "nsg": { "icon_svg": '', "color": "#5C2D91", "bg": "#F3EEF9", "category": "Network", "azure_icon_key": "network_security_groups" }, "acr": { "icon_svg": 'ACR', "color": "#0078D4", "bg": "#E8F4FD", "category": "Compute" }, "aks": { "icon_svg": 'K', "color": "#326CE5", "bg": "#EBF0FC", "category": "Compute", "azure_icon_key": "kubernetes_services" }, "appservice": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Compute", "azure_icon_key": "app_services" }, "appinsights": { "icon_svg": '', "color": "#773ADC", "bg": "#F0EAFA", "category": "Monitor", "azure_icon_key": "application_insights" }, "monitor": { "icon_svg": '', "color": "#773ADC", "bg": "#F0EAFA", "category": "Monitor", "azure_icon_key": "monitor" }, "vm": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Compute", "azure_icon_key": "virtual_machine" }, "bastion": { "icon_svg": '', "color": "#5C2D91", "bg": "#F3EEF9", "category": "Network", "azure_icon_key": "bastions" }, "jumpbox": { "icon_svg": 'JB', "color": "#5C2D91", "bg": "#F3EEF9", "category": "Network", "azure_icon_key": "virtual_machine" }, "vpn": { "icon_svg": '', "color": "#5C2D91", "bg": "#F3EEF9", "category": "Network", "azure_icon_key": "virtual_network_gateways" }, "user": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "External" }, "app": { "icon_svg": '', "color": "#666666", "bg": "#F5F5F5", "category": "External" }, "default": { "icon_svg": '?', "color": "#0078D4", "bg": "#E8F4FD", "category": "Azure" }, "cdn": { "icon_svg": 'CDN', "color": "#0078D4", "bg": "#E8F4FD", "category": "Network", "azure_icon_key": "cdn_profiles" }, "event_hub": { "icon_svg": 'EventHub', "color": "#0078D4", "bg": "#E8F4FD", "category": "Integration", "azure_icon_key": "event_hubs" }, "redis": { "icon_svg": 'Redis', "color": "#D83B01", "bg": "#FEF0E8", "category": "Data", "azure_icon_key": "cache_redis" }, "devops": { "icon_svg": 'DevOps', "color": "#0078D4", "bg": "#E8F4FD", "category": "DevOps", "azure_icon_key": "azure_devops" }, "acr": { "icon_svg": 'ACR', "color": "#0078D4", "bg": "#E8F4FD", "category": "Compute", "azure_icon_key": "container_registries" }, "container_registry": { "icon_svg": 'ACR', "color": "#0078D4", "bg": "#E8F4FD", "category": "Compute", "azure_icon_key": "container_registries" }, "app_gateway": { "icon_svg": 'AppGW', "color": "#0078D4", "bg": "#E8F4FD", "category": "Network", "azure_icon_key": "application_gateways" }, "iot_hub": { "icon_svg": 'IoTHub', "color": "#0078D4", "bg": "#E8F4FD", "category": "IoT", "azure_icon_key": "iot_hub" }, "stream_analytics": { "icon_svg": 'StreamAnalytics', "color": "#0078D4", "bg": "#E8F4FD", "category": "Data", "azure_icon_key": "stream_analytics_jobs" }, "vpn_gateway": { "icon_svg": '', "color": "#5C2D91", "bg": "#F3EEF9", "category": "Network", "azure_icon_key": "virtual_network_gateways" }, "front_door": { "icon_svg": 'FrontDoor', "color": "#0078D4", "bg": "#E8F4FD", "category": "Network", "azure_icon_key": "front_door_and_cdn_profiles" }, "ai_hub": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "AI", "azure_icon_key": "ai_studio" }, "firewall": { "icon_svg": 'Firewall', "color": "#E8A000", "bg": "#FFF8E1", "category": "Network", "azure_icon_key": "firewalls" }, "document_intelligence": { "icon_svg": 'DocIntel', "color": "#0078D4", "bg": "#E8F4FD", "category": "AI", "azure_icon_key": "form_recognizer" }, "form_recognizer": { "icon_svg": 'DocIntel', "color": "#0078D4", "bg": "#E8F4FD", "category": "AI", "azure_icon_key": "form_recognizer" }, "databricks": { "icon_svg": 'DB', "color": "#FF3621", "bg": "#FFF0EE", "category": "Data", "azure_icon_key": "azure_databricks" }, "sql_server": { "icon_svg": 'SQL', "color": "#0078D4", "bg": "#E8F4FD", "category": "Data", "azure_icon_key": "sql_server" }, "sql_database": { "icon_svg": 'SQL', "color": "#0078D4", "bg": "#E8F4FD", "category": "Data", "azure_icon_key": "sql_database" }, "cosmos_db": { "icon_svg": 'CosmosDB', "color": "#0078D4", "bg": "#E8F4FD", "category": "Data", "azure_icon_key": "azure_cosmos_db" }, "app_service": { "icon_svg": 'App', "color": "#0078D4", "bg": "#E8F4FD", "category": "Compute", "azure_icon_key": "app_services" }, "aks": { "icon_svg": 'K8s', "color": "#326CE5", "bg": "#EBF0FA", "category": "Compute", "azure_icon_key": "kubernetes_services" }, "function_app": { "icon_svg": 'ƒ', "color": "#F0AD4E", "bg": "#FFF8ED", "category": "Compute", "azure_icon_key": "function_apps" }, "synapse": { "icon_svg": 'Synapse', "color": "#0078D4", "bg": "#E8F4FD", "category": "Data", "azure_icon_key": "azure_synapse_analytics" }, "log_analytics": { "icon_svg": 'Log', "color": "#5C2D91", "bg": "#F3EDF7", "category": "Monitoring", "azure_icon_key": "log_analytics_workspaces" }, "app_insights": { "icon_svg": 'AI', "color": "#5C2D91", "bg": "#F3EDF7", "category": "Monitoring", "azure_icon_key": "application_insights" }, "nsg": { "icon_svg": 'NSG', "color": "#E8A000", "bg": "#FFF8E1", "category": "Network", "azure_icon_key": "network_security_groups" }, "apim": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Integration", "azure_icon_key": "api_management_services" }, "api_management": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Integration", "azure_icon_key": "api_management_services" }, "service_bus": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Integration", "azure_icon_key": "azure_service_bus" }, "logic_apps": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Integration", "azure_icon_key": "logic_apps" }, "logic_app": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Integration", "azure_icon_key": "logic_apps" }, "event_grid": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Integration", "azure_icon_key": "event_grid_topics" }, "container_apps": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Compute", "azure_icon_key": "container_apps_environments" }, "container_app": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Compute", "azure_icon_key": "container_apps_environments" }, "postgresql": { "icon_svg": 'PG', "color": "#0078D4", "bg": "#E8F4FD", "category": "Data", "azure_icon_key": "azure_database_postgresql_server" }, "mysql": { "icon_svg": 'My', "color": "#0078D4", "bg": "#E8F4FD", "category": "Data", "azure_icon_key": "azure_database_mysql_server" }, "load_balancer": { "icon_svg": '', "color": "#5C2D91", "bg": "#F3EEF9", "category": "Network", "azure_icon_key": "load_balancers" }, "nat_gateway": { "icon_svg": 'NAT', "color": "#5C2D91", "bg": "#F3EEF9", "category": "Network", "azure_icon_key": "nat" }, "expressroute": { "icon_svg": '', "color": "#5C2D91", "bg": "#F3EEF9", "category": "Network", "azure_icon_key": "expressroute_circuits" }, "sentinel": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Security", "azure_icon_key": "azure_sentinel" }, "data_explorer": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Data", "azure_icon_key": "azure_data_explorer_clusters" }, "kusto": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Data", "azure_icon_key": "azure_data_explorer_clusters" }, "signalr": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Integration", "azure_icon_key": "signalr" }, "notification_hub": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Integration", "azure_icon_key": "notification_hubs" }, "spring_apps": { "icon_svg": '🌱', "color": "#6DB33F", "bg": "#EFF8E8", "category": "Compute", "azure_icon_key": "azure_spring_apps" }, "static_web_app": { "icon_svg": 'SWA', "color": "#0078D4", "bg": "#E8F4FD", "category": "Compute", "azure_icon_key": "static_apps" }, "digital_twins": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "IoT", "azure_icon_key": "digital_twins" }, "backup": { "icon_svg": '', "color": "#0078D4", "bg": "#E8F4FD", "category": "Management", "azure_icon_key": "backup_vault" }, } CONNECTION_STYLES = { "api": {"color": "#0078D4", "dash": "0"}, "data": {"color": "#0F9D58", "dash": "0"}, "security": {"color": "#E8A000", "dash": "5,5"}, "private": {"color": "#5C2D91", "dash": "3,3"}, "network": {"color": "#5C2D91", "dash": "5,5"}, "default": {"color": "#999999", "dash": "0"}, } def get_service_info(svc_type: str) -> dict: t = svc_type.lower().replace("-", "_").replace(" ", "_") info = SERVICE_ICONS.get(t, SERVICE_ICONS["default"]).copy() # Add official Azure icon data URI if available azure_key = info.get("azure_icon_key", t) icon_uri = get_icon_data_uri(azure_key) info["icon_data_uri"] = icon_uri return info def generate_html(services: list, connections: list, title: str, vnet_info: str = "", hierarchy: list = None) -> str: nodes_js = json.dumps([{ "id": svc["id"], "name": svc["name"], "type": svc.get("type", "default"), "sku": svc.get("sku", ""), "private": svc.get("private", False), "details": svc.get("details", []), "subscription": svc.get("subscription", ""), "resourceGroup": svc.get("resourceGroup", ""), "icon_svg": get_service_info(svc.get("type", "default"))["icon_svg"], "icon_data_uri": get_service_info(svc.get("type", "default")).get("icon_data_uri", ""), "color": get_service_info(svc.get("type", "default"))["color"], "bg": get_service_info(svc.get("type", "default"))["bg"], "category": get_service_info(svc.get("type", "default"))["category"], } for svc in services], ensure_ascii=False) hierarchy_js = json.dumps(hierarchy or [], ensure_ascii=False) edges_js = json.dumps([{ "from": conn["from"], "to": conn["to"], "label": conn.get("label", ""), "type": conn.get("type", "default"), "color": CONNECTION_STYLES.get(conn.get("type", "default"), CONNECTION_STYLES["default"])["color"], "dash": CONNECTION_STYLES.get(conn.get("type", "default"), CONNECTION_STYLES["default"])["dash"], } for conn in connections], ensure_ascii=False) pe_count = sum(1 for s in services if s.get("type", "default") == "pe") svc_count = len(services) - pe_count generated_at = datetime.now().strftime("%Y-%m-%d %H:%M") vnet_info_js = json.dumps(vnet_info, ensure_ascii=False) html = f""" {title}

{title}

Azure Architecture · {generated_at}
{svc_count} Services
{pe_count} Private Endpoints
{len(connections)} Connections
100%
Drag nodes · Scroll to zoom · Drag empty space to pan
""" return html def generate_diagram(services, connections, title="Azure Architecture", vnet_info="", hierarchy=None): """Generate an interactive Azure architecture diagram as an HTML string. Args: services: list of dicts with keys id, name, type, sku, private, details, etc. connections: list of dicts with keys from, to, label, type. title: diagram title string. vnet_info: VNet CIDR info string. hierarchy: optional subscription/RG hierarchy list. Returns: HTML string containing the interactive diagram. """ return generate_html(services, connections, title, vnet_info=vnet_info, hierarchy=hierarchy)