-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexamples.py
More file actions
180 lines (149 loc) · 6 KB
/
examples.py
File metadata and controls
180 lines (149 loc) · 6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
"""Showcase examples for specplot README."""
from specplot import diagram, node, edge
def hero_example():
"""Hero example: Shows all key features in one compact diagram."""
with diagram(
filename="docs/hero"
):
# Node without description
user = node(icon="person", label="User")
# Group node with children (grid layout)
with node(
icon="cloud",
label="Our WebApp",
description="Layered architecture style.",
show_as="group",
grid=(3, 1)
) as app:
node(icon="web", label="Presentation Layer",
description="User interface components")
node(icon="account_tree", label="Business Layer",
description="Business logic and rules")
persistance = node(icon="storage", label="Persistence Layer",
description="Data access and ORM")
# Outline node (bullet list style)
with node(
icon="database",
label="Database Layer",
show_as="outline"
) as dbs:
node(label="PostgreSQL")
node(label="Redis Cache")
# Edges with and without labels
user >> app
persistance >> dbs | "read/write"
def example_pipeline():
"""Example 3: ML Data Pipeline with mixed modes."""
with diagram(
filename="docs/example_pipeline",
layout=(
("LR",), # Sources
("LR", "LR"), # Ingestion + Processing
("LR",), # Lake
("LR", "LR"), # ML + Outputs
)
):
# Data sources
with node(icon="source", label="Data Sources", show_as="group", grid=(1, 3), pos=1):
api_src = node(icon="api", label="APIs")
db_src = node(icon="database", label="Databases")
files = node(icon="folder", label="Files")
# Ingestion
ingest = node(icon="input", label="Ingestion",
description="Kafka / Kinesis", pos=2)
# Processing with outline
with node(icon="memory", label="Processing",
description="Spark / Flink",
show_as="outline", pos=3) as proc:
node(label="Validation")
node(label="Feature Engineering")
node(label="Aggregations")
# Storage
lake = node(icon="waves", label="Data Lake",
description="S3 / Delta Lake", pos=4)
# ML Pipeline as group
with node(icon="psychology", label="ML Pipeline", show_as="group", grid=(2, 1), pos=5) as ml:
train = node(icon="model_training", label="Training")
serve = node(icon="cloud_upload", label="Serving")
# Outputs
with node(icon="analytics", label="Outputs", show_as="group", grid=(2, 1), pos=6):
dash = node(icon="dashboard", label="Dashboards")
alerts = node(icon="notifications", label="Alerts")
# Flow
api_src >> ingest
db_src >> ingest
files >> ingest
ingest >> proc | "stream"
proc >> lake | "batch"
lake >> ml | "features"
train >> serve | "deploy"
serve >> dash | "predictions"
serve >> alerts | "anomalies"
def example_event_driven():
"""Event-Driven Architecture - Broker topology.
Reference: Fundamentals of Software Architecture, Chapter 14
"""
with diagram(
filename="docs/example_event_driven",
pathfinding=False,
layout=(
("TB", "TB", "TB"), # Initiator, channels, processors
)
):
# Initiating Event
initiator = node(
icon="bolt",
label="Initiating Event",
description="Triggers the flow",
pos=1
)
# Event Channels (broker)
with node(
icon="sync_alt",
label="Event Channels",
description="Message broker",
show_as="group",
grid=(3, 1),
pos=2
) as channels:
ch1 = node(icon="valve", label="Event Channel 1")
ch2 = node(icon="valve", label="Event Channel 2")
ch3 = node(icon="valve", label="Event Channel 3")
# Event Processors (left side)
with node(icon="settings", label="Processor", show_as="outline", pos=1) as proc2:
node(label="Component")
node(label="Component")
with node(icon="settings", label="Processor", show_as="group", grid=(3, 1), pos=1) as proc4:
node(label="Component")
node(label="Component")
proc_event2 = node(icon="bolt", label="Processing Event")
# Event Processors (right side)
with node(icon="settings", label="Processor", show_as="group", grid=(3, 1), pos=3) as proc1:
node(label="Component")
node(label="Component")
proc1_event = node(icon="bolt", label="Processing Event")
with node(icon="settings", label="Processor", show_as="outline", pos=3) as proc3:
node(label="Component")
node(label="Component")
with node(icon="settings", label="Processor", show_as="outline", pos=3) as proc5:
node(label="Component")
node(label="Component")
# Connections
edge(initiator, ch1, style='..>')
edge(ch1, proc1, style='..>')
edge(proc1_event, ch2, style='..>')
edge(ch2, proc2, style='..>')
edge(ch2, proc3, style='..>')
edge(ch2, proc4, style='..>')
edge(proc_event2, ch3, style='..>')
edge(ch3, proc5, style='..>')
if __name__ == "__main__":
import os
os.makedirs("docs", exist_ok=True)
print("Generating hero example...")
hero_example()
print("Generating data pipeline example...")
example_pipeline()
print("Generating event-driven architecture...")
example_event_driven()
print("\nAll examples generated in docs/")