Skip to content

Commit c0917bd

Browse files
committed
Add gzip compression nodes
1 parent 172d383 commit c0917bd

File tree

4 files changed

+153
-0
lines changed

4 files changed

+153
-0
lines changed

docs/nodetool_compression.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
layout: default
3+
title: nodetool.compression
4+
parent: Nodes
5+
has_children: false
6+
nav_order: 2
7+
---
8+
9+
# nodetool.nodes.nodetool.compression
10+
11+
Nodes for compressing and decompressing data with gzip.
12+
13+
## GzipCompress
14+
15+
Compress bytes using gzip.
16+
17+
Use cases:
18+
- Reduce size of binary data
19+
- Store assets in compressed form
20+
- Prepare data for network transfer
21+
22+
**Tags:** gzip, compress, bytes
23+
24+
**Fields:**
25+
- **data**: Data to compress (bytes)
26+
27+
## GzipDecompress
28+
29+
Decompress gzip data.
30+
31+
Use cases:
32+
- Restore compressed files
33+
- Read data from gzip archives
34+
- Process network payloads
35+
36+
**Tags:** gzip, decompress, bytes
37+
38+
**Fields:**
39+
- **data**: Gzip data to decompress (bytes)
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from pydantic import BaseModel, Field
2+
import typing
3+
from typing import Any
4+
import nodetool.metadata.types
5+
import nodetool.metadata.types as types
6+
from nodetool.dsl.graph import GraphNode
7+
8+
9+
class GzipCompress(GraphNode):
10+
"""
11+
Compress bytes using gzip.
12+
gzip, compress, bytes
13+
14+
Use cases:
15+
- Reduce size of binary data
16+
- Store assets in compressed form
17+
- Prepare data for network transfer
18+
"""
19+
20+
data: bytes | None | GraphNode | tuple[GraphNode, str] = Field(default=None, description='Data to compress')
21+
22+
@classmethod
23+
def get_node_type(cls): return "nodetool.compression.GzipCompress"
24+
25+
26+
27+
class GzipDecompress(GraphNode):
28+
"""
29+
Decompress gzip data.
30+
gzip, decompress, bytes
31+
32+
Use cases:
33+
- Restore compressed files
34+
- Read data from gzip archives
35+
- Process network payloads
36+
"""
37+
38+
data: bytes | None | GraphNode | tuple[GraphNode, str] = Field(default=None, description='Gzip data to decompress')
39+
40+
@classmethod
41+
def get_node_type(cls): return "nodetool.compression.GzipDecompress"
42+
43+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import gzip
2+
from pydantic import Field
3+
from nodetool.workflows.base_node import BaseNode
4+
from nodetool.workflows.processing_context import ProcessingContext
5+
6+
7+
class GzipCompress(BaseNode):
8+
"""
9+
Compress bytes using gzip.
10+
gzip, compress, bytes
11+
12+
Use cases:
13+
- Reduce size of binary data
14+
- Store assets in compressed form
15+
- Prepare data for network transfer
16+
"""
17+
18+
data: bytes | None = Field(default=None, description="Data to compress")
19+
20+
async def process(self, context: ProcessingContext) -> bytes:
21+
if not self.data:
22+
raise ValueError("data cannot be empty")
23+
return gzip.compress(self.data)
24+
25+
26+
class GzipDecompress(BaseNode):
27+
"""
28+
Decompress gzip data.
29+
gzip, decompress, bytes
30+
31+
Use cases:
32+
- Restore compressed files
33+
- Read data from gzip archives
34+
- Process network payloads
35+
"""
36+
37+
data: bytes | None = Field(
38+
default=None,
39+
description="Gzip data to decompress",
40+
)
41+
42+
async def process(self, context: ProcessingContext) -> bytes:
43+
if not self.data:
44+
raise ValueError("data cannot be empty")
45+
return gzip.decompress(self.data)

tests/nodetool/test_gzip_nodes.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import gzip
2+
import pytest
3+
from nodetool.workflows.processing_context import ProcessingContext
4+
from nodetool.nodes.nodetool.compression import GzipCompress, GzipDecompress
5+
6+
7+
@pytest.fixture
8+
def context():
9+
return ProcessingContext(user_id="test", auth_token="test")
10+
11+
12+
@pytest.mark.asyncio
13+
async def test_gzip_compress(context: ProcessingContext):
14+
data = b"hello world"
15+
node = GzipCompress(data=data)
16+
result = await node.process(context)
17+
assert gzip.decompress(result) == data
18+
19+
20+
@pytest.mark.asyncio
21+
async def test_gzip_decompress(context: ProcessingContext):
22+
data = b"compress me"
23+
compressed = gzip.compress(data)
24+
node = GzipDecompress(data=compressed)
25+
result = await node.process(context)
26+
assert result == data

0 commit comments

Comments
 (0)