Examples
This section provides complete, working examples for VeilData streaming functionality.
Streaming Examples
The following examples demonstrate various streaming redaction use cases.
Example 1: Basic Streaming
This example shows basic chunk-based streaming with cross-chunk entity detection.
1def example_1_basic_streaming():
2 """Basic example of streaming redaction."""
3 print("=== Example 1: Basic Streaming ===\n")
4
5 # Setup detector
6 patterns = {
7 "EMAIL": r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
8 "PHONE": r"\d{3}-\d{4}",
9 }
10 detector = RegexDetector(patterns)
11 pipeline = DetectionPipeline(detector)
12
13 # Create buffer
14 buffer = StreamingRedactionBuffer(pipeline, overlap_size=20)
15
16 # Simulate chunks (in real use, these would come from a file or stream)
17 chunks = [
18 "My email is john.do",
19 "[email protected] and my phone is 555-",
20 "1234. Contact me anytime!",
21 ]
22
23 print("Processing chunks...")
24 for i, chunk in enumerate(chunks, 1):
25 output = buffer.add_chunk(chunk)
26 print(f"Chunk {i}: {chunk!r}")
27 print(f" Output: {output!r}")
28
29 final = buffer.finalize()
30 print(f"Final: {final!r}\n")
31
32 # Get stats
33 stats = buffer.get_stats()
34 print(f"Stats: {stats}\n")
Example 2: File Streaming
Process a file in chunks and write the redacted output.
1def example_2_file_streaming():
2 """Example of streaming a file."""
3 print("=== Example 2: File Streaming ===\n")
4
5 # Create a test file
6 with open("test_input.txt", "w") as f:
7 for i in range(10):
8 f.write(f"Line {i}: Contact user{i}@example.com or call 555-{i:04d}\n")
9
10 # Setup
11 patterns = {"EMAIL": r"\S+@\S+", "PHONE": r"\d{3}-\d{4}"}
12 detector = RegexDetector(patterns)
13 pipeline = DetectionPipeline(detector)
14 store = TokenStore()
15
16 def read_file_chunks(filepath, chunk_size=100):
17 """Generator that yields file chunks."""
18 with open(filepath, "r") as f:
19 while True:
20 chunk = f.read(chunk_size)
21 if not chunk:
22 break
23 yield chunk
24
25 # Process using stream_redact
26 print("Redacting test_input.txt...")
27 output_chunks = list(
28 stream_redact(
29 read_file_chunks("test_input.txt"), pipeline, overlap_size=30, store=store
30 )
31 )
32
33 # Write output
34 with open("test_output.txt", "w") as f:
35 f.write("".join(output_chunks))
36
37 print("✓ Redacted to test_output.txt")
38 print(f"✓ Found {len(store.mappings)} entities\n")
39
40 # Show first few mappings
41 for i, (token, original) in enumerate(list(store.mappings.items())[:5], 1):
42 print(f" {token} → {original}")
43
44 print()
Example 3: API Usage
Instructions for using the streaming API endpoint.
1def example_3_api_usage():
2 """Example of using the streaming API."""
3 print("=== Example 3: API Usage ===\n")
4
5 print("To use the streaming API:")
6 print()
7 print("1. Start the API server:")
8 print(" $ uvicorn veildata.api.app:app --reload")
9 print()
10 print("2. Stream redaction with curl:")
11 print(' $ curl -X POST "http://localhost:8000/v1/redact/stream" \\')
12 print(' -H "Content-Type: text/plain" \\')
13 print(" --data-binary @input.txt > output.txt")
14 print()
15 print("3. With custom parameters:")
16 print(
17 ' $ curl -X POST "http://localhost:8000/v1/redact/stream?overlap_size=256&return_store=true" \\'
18 )
19 print(' -H "Content-Type: text/plain" \\')
20 print(" --data-binary @input.txt -v 2>&1 | grep -i x-token-store")
21 print()
Example 4: CLI Usage
Command-line examples for streaming mode.
1def example_4_cli_usage():
2 """Example of using the CLI streaming mode."""
3 print("=== Example 4: CLI Usage ===\n")
4
5 print("Stream redaction from command line:")
6 print()
7 print("1. Basic streaming:")
8 print(" $ veildata redact input.txt --stream --output output.txt")
9 print()
10 print("2. With custom chunk and overlap sizes:")
11 print(" $ veildata redact large_file.txt --stream \\")
12 print(" --chunk-size 8192 --overlap 1024 \\")
13 print(" --output redacted.txt --store store.json")
14 print()
15 print("3. With timing and verbose output:")
16 print(" $ veildata redact input.txt --stream --time --verbose \\")
17 print(" --output output.txt")
18 print()
19 print("4. Pipe stdin:")
20 print(" $ cat large_file.txt | veildata redact --stream > output.txt")
21 print()
Complete Example File
View the complete example file with all functions:
1"""
2Example demonstrating streaming redaction with VeilData.
3
4This example shows how to:
51. Process large files in chunks using the streaming buffer
62. Use the streaming API endpoint
73. Handle cross-chunk entity detection
8"""
9
10from veildata.detectors import RegexDetector
11from veildata.pipeline import DetectionPipeline
12from veildata.revealers import TokenStore
13from veildata.streaming_buffer import StreamingRedactionBuffer, stream_redact
14
15
16def example_1_basic_streaming():
17 """Basic example of streaming redaction."""
18 print("=== Example 1: Basic Streaming ===\n")
19
20 # Setup detector
21 patterns = {
22 "EMAIL": r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
23 "PHONE": r"\d{3}-\d{4}",
24 }
25 detector = RegexDetector(patterns)
26 pipeline = DetectionPipeline(detector)
27
28 # Create buffer
29 buffer = StreamingRedactionBuffer(pipeline, overlap_size=20)
30
31 # Simulate chunks (in real use, these would come from a file or stream)
32 chunks = [
33 "My email is john.do",
34 "[email protected] and my phone is 555-",
35 "1234. Contact me anytime!",
36 ]
37
38 print("Processing chunks...")
39 for i, chunk in enumerate(chunks, 1):
40 output = buffer.add_chunk(chunk)
41 print(f"Chunk {i}: {chunk!r}")
42 print(f" Output: {output!r}")
43
44 final = buffer.finalize()
45 print(f"Final: {final!r}\n")
46
47 # Get stats
48 stats = buffer.get_stats()
49 print(f"Stats: {stats}\n")
50
51
52def example_2_file_streaming():
53 """Example of streaming a file."""
54 print("=== Example 2: File Streaming ===\n")
55
56 # Create a test file
57 with open("test_input.txt", "w") as f:
58 for i in range(10):
59 f.write(f"Line {i}: Contact user{i}@example.com or call 555-{i:04d}\n")
60
61 # Setup
62 patterns = {"EMAIL": r"\S+@\S+", "PHONE": r"\d{3}-\d{4}"}
63 detector = RegexDetector(patterns)
64 pipeline = DetectionPipeline(detector)
65 store = TokenStore()
66
67 def read_file_chunks(filepath, chunk_size=100):
68 """Generator that yields file chunks."""
69 with open(filepath, "r") as f:
70 while True:
71 chunk = f.read(chunk_size)
72 if not chunk:
73 break
74 yield chunk
75
76 # Process using stream_redact
77 print("Redacting test_input.txt...")
78 output_chunks = list(
79 stream_redact(
80 read_file_chunks("test_input.txt"), pipeline, overlap_size=30, store=store
81 )
82 )
83
84 # Write output
85 with open("test_output.txt", "w") as f:
86 f.write("".join(output_chunks))
87
88 print("✓ Redacted to test_output.txt")
89 print(f"✓ Found {len(store.mappings)} entities\n")
90
91 # Show first few mappings
92 for i, (token, original) in enumerate(list(store.mappings.items())[:5], 1):
93 print(f" {token} → {original}")
94
95 print()
96
97
98def example_3_api_usage():
99 """Example of using the streaming API."""
100 print("=== Example 3: API Usage ===\n")
101
102 print("To use the streaming API:")
103 print()
104 print("1. Start the API server:")
105 print(" $ uvicorn veildata.api.app:app --reload")
106 print()
107 print("2. Stream redaction with curl:")
108 print(' $ curl -X POST "http://localhost:8000/v1/redact/stream" \\')
109 print(' -H "Content-Type: text/plain" \\')
110 print(" --data-binary @input.txt > output.txt")
111 print()
112 print("3. With custom parameters:")
113 print(
114 ' $ curl -X POST "http://localhost:8000/v1/redact/stream?overlap_size=256&return_store=true" \\'
115 )
116 print(' -H "Content-Type: text/plain" \\')
117 print(" --data-binary @input.txt -v 2>&1 | grep -i x-token-store")
118 print()
119
120
121def example_4_cli_usage():
122 """Example of using the CLI streaming mode."""
123 print("=== Example 4: CLI Usage ===\n")
124
125 print("Stream redaction from command line:")
126 print()
127 print("1. Basic streaming:")
128 print(" $ veildata redact input.txt --stream --output output.txt")
129 print()
130 print("2. With custom chunk and overlap sizes:")
131 print(" $ veildata redact large_file.txt --stream \\")
132 print(" --chunk-size 8192 --overlap 1024 \\")
133 print(" --output redacted.txt --store store.json")
134 print()
135 print("3. With timing and verbose output:")
136 print(" $ veildata redact input.txt --stream --time --verbose \\")
137 print(" --output output.txt")
138 print()
139 print("4. Pipe stdin:")
140 print(" $ cat large_file.txt | veildata redact --stream > output.txt")
141 print()
142
143
144def main():
145 """Run all examples."""
146 example_1_basic_streaming()
147 example_2_file_streaming()
148 example_3_api_usage()
149 example_4_cli_usage()
150
151 print("=" * 50)
152 print("Examples complete! Check test_output.txt for results.")
153 print("=" * 50)
154
155
156if __name__ == "__main__":
157 main()
Running the Examples
To run the complete example:
cd examples
python streaming_example.py
This will:
Demonstrate basic buffer usage with console output
Create test files (
test_input.txt,test_output.txt)Show token store mappings
Display API and CLI usage instructions
Additional Examples
Integration with Custom Detectors
from veildata.detectors import RegexDetector, SpacyDetector
from veildata.pipeline import DetectionPipeline
from veildata.streaming_buffer import stream_redact
# Combine multiple detectors
patterns = {
"EMAIL": r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
"PHONE": r"\d{3}-\d{3}-\d{4}",
}
regex_detector = RegexDetector(patterns)
pipeline = DetectionPipeline(regex_detector)
# Stream from generator
def chunk_generator(filepath):
with open(filepath, 'r') as f:
while True:
chunk = f.read(4096)
if not chunk:
break
yield chunk
# Process stream
for output in stream_redact(chunk_generator("input.txt"), pipeline):
print(output, end="")
Progress Tracking
Track progress while streaming large files:
from veildata.streaming_buffer import StreamingRedactionBuffer
from veildata.engine import build_redactor
redactor, store = build_redactor(method="regex")
buffer = StreamingRedactionBuffer(redactor, overlap_size=512)
file_size = os.path.getsize("large_file.txt")
processed = 0
with open("large_file.txt") as f:
while chunk := f.read(4096):
processed += len(chunk)
output = buffer.add_chunk(chunk)
# Show progress
percent = (processed / file_size) * 100
print(f"\rProgress: {percent:.1f}%", end="", flush=True)
# Write output
# ... handle output ...
final = buffer.finalize()
print(f"\n✓ Complete! {buffer.get_stats()['total_entities_redacted']} entities redacted")
Memory-Efficient Pipeline
For extremely large files, write directly to output without accumulating:
from veildata.streaming_buffer import StreamingRedactionBuffer
from veildata.engine import build_redactor
redactor, store = build_redactor(method="regex")
buffer = StreamingRedactionBuffer(redactor, overlap_size=512)
with open("input.txt") as infile, open("output.txt", "w") as outfile:
while chunk := infile.read(8192): # 8KB chunks
redacted = buffer.add_chunk(chunk)
if redacted:
outfile.write(redacted)
# Don't forget the final chunk
final = buffer.finalize()
if final:
outfile.write(final)
# Save store for reversibility
store.save("store.json")
See Also
Streaming Redaction - Detailed streaming documentation
API Reference - API reference
Command Line Interface - Command-line usage