flow.record 3.17.dev5__tar.gz → 3.17.dev7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. {flow_record-3.17.dev5/flow.record.egg-info → flow_record-3.17.dev7}/PKG-INFO +2 -3
  2. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/fieldtypes/net/ip.py +37 -18
  3. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/version.py +2 -2
  4. {flow_record-3.17.dev5 → flow_record-3.17.dev7/flow.record.egg-info}/PKG-INFO +2 -3
  5. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow.record.egg-info/requires.txt +0 -3
  6. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/pyproject.toml +1 -2
  7. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_fieldtype_ip.py +15 -0
  8. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tox.ini +1 -1
  9. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/COPYRIGHT +0 -0
  10. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/LICENSE +0 -0
  11. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/MANIFEST.in +0 -0
  12. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/README.md +0 -0
  13. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/examples/filesystem.py +0 -0
  14. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/examples/passivedns.py +0 -0
  15. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/examples/records.json +0 -0
  16. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/examples/tcpconn.py +0 -0
  17. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/__init__.py +0 -0
  18. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/adapter/__init__.py +0 -0
  19. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/adapter/archive.py +0 -0
  20. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/adapter/avro.py +0 -0
  21. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/adapter/broker.py +0 -0
  22. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/adapter/csvfile.py +0 -0
  23. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/adapter/duckdb.py +0 -0
  24. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/adapter/elastic.py +0 -0
  25. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/adapter/jsonfile.py +0 -0
  26. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/adapter/line.py +0 -0
  27. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/adapter/mongo.py +0 -0
  28. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/adapter/split.py +0 -0
  29. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/adapter/splunk.py +0 -0
  30. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/adapter/sqlite.py +0 -0
  31. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/adapter/stream.py +0 -0
  32. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/adapter/text.py +0 -0
  33. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/adapter/xlsx.py +0 -0
  34. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/base.py +0 -0
  35. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/exceptions.py +0 -0
  36. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/fieldtypes/__init__.py +0 -0
  37. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/fieldtypes/credential.py +0 -0
  38. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/fieldtypes/net/__init__.py +0 -0
  39. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/fieldtypes/net/ipv4.py +0 -0
  40. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/fieldtypes/net/tcp.py +0 -0
  41. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/fieldtypes/net/udp.py +0 -0
  42. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/jsonpacker.py +0 -0
  43. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/packer.py +0 -0
  44. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/selector.py +0 -0
  45. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/stream.py +0 -0
  46. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/tools/__init__.py +0 -0
  47. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/tools/geoip.py +0 -0
  48. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/tools/rdump.py +0 -0
  49. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/utils.py +0 -0
  50. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow/record/whitelist.py +0 -0
  51. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow.record.egg-info/SOURCES.txt +0 -0
  52. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow.record.egg-info/dependency_links.txt +0 -0
  53. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow.record.egg-info/entry_points.txt +0 -0
  54. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/flow.record.egg-info/top_level.txt +0 -0
  55. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/setup.cfg +0 -0
  56. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/__init__.py +0 -0
  57. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/_utils.py +0 -0
  58. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/docs/Makefile +0 -0
  59. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/docs/conf.py +0 -0
  60. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/docs/index.rst +0 -0
  61. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/selector_explain_example.py +0 -0
  62. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/standalone_test.py +0 -0
  63. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_adapter_line.py +0 -0
  64. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_adapter_text.py +0 -0
  65. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_avro.py +0 -0
  66. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_avro_adapter.py +0 -0
  67. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_compiled_selector.py +0 -0
  68. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_csv_adapter.py +0 -0
  69. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_deprecations.py +0 -0
  70. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_elastic_adapter.py +0 -0
  71. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_fieldtypes.py +0 -0
  72. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_json_packer.py +0 -0
  73. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_json_record_adapter.py +0 -0
  74. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_multi_timestamp.py +0 -0
  75. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_packer.py +0 -0
  76. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_rdump.py +0 -0
  77. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_record.py +0 -0
  78. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_record_adapter.py +0 -0
  79. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_record_descriptor.py +0 -0
  80. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_regression.py +0 -0
  81. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_selector.py +0 -0
  82. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_splunk_adapter.py +0 -0
  83. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_sqlite_duckdb_adapter.py +0 -0
  84. {flow_record-3.17.dev5 → flow_record-3.17.dev7}/tests/test_xlsx_adapter.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flow.record
3
- Version: 3.17.dev5
3
+ Version: 3.17.dev7
4
4
  Summary: A library for defining and creating structured data (called records) that can be streamed to disk or piped to other tools that use flow.record
5
5
  Author-email: Dissect Team <dissect@fox-it.com>
6
6
  License: Affero General Public License v3
@@ -16,12 +16,11 @@ Classifier: Operating System :: OS Independent
16
16
  Classifier: Programming Language :: Python :: 3
17
17
  Classifier: Topic :: Scientific/Engineering :: Information Analysis
18
18
  Classifier: Topic :: Utilities
19
- Requires-Python: ~=3.8
19
+ Requires-Python: ~=3.9
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
22
  License-File: COPYRIGHT
23
23
  Requires-Dist: msgpack>=0.5.2
24
- Requires-Dist: backports.zoneinfo[tzdata]; python_version < "3.9"
25
24
  Requires-Dist: tzdata; platform_system == "Windows"
26
25
  Provides-Extra: compression
27
26
  Requires-Dist: lz4; extra == "compression"
@@ -1,38 +1,54 @@
1
- from ipaddress import ip_address, ip_network
1
+ from __future__ import annotations
2
+
3
+ from ipaddress import (
4
+ IPv4Address,
5
+ IPv4Network,
6
+ IPv6Address,
7
+ IPv6Network,
8
+ ip_address,
9
+ ip_network,
10
+ )
11
+ from typing import Union
2
12
 
3
13
  from flow.record.base import FieldType
4
14
  from flow.record.fieldtypes import defang
5
15
 
16
+ _IPNetwork = Union[IPv4Network, IPv6Network]
17
+ _IPAddress = Union[IPv4Address, IPv6Address]
18
+
6
19
 
7
20
  class ipaddress(FieldType):
8
21
  val = None
9
22
  _type = "net.ipaddress"
10
23
 
11
- def __init__(self, addr):
24
+ def __init__(self, addr: str | int | bytes):
12
25
  self.val = ip_address(addr)
13
26
 
14
- def __eq__(self, b):
27
+ def __eq__(self, b: str | int | bytes | _IPAddress) -> bool:
15
28
  try:
16
29
  return self.val == ip_address(b)
17
30
  except ValueError:
18
31
  return False
19
32
 
20
- def __str__(self):
33
+ def __hash__(self) -> int:
34
+ return hash(self.val)
35
+
36
+ def __str__(self) -> str:
21
37
  return str(self.val)
22
38
 
23
- def __repr__(self):
24
- return "{}({!r})".format(self._type, str(self))
39
+ def __repr__(self) -> str:
40
+ return f"{self._type}({str(self)!r})"
25
41
 
26
- def __format__(self, spec):
42
+ def __format__(self, spec: str) -> str:
27
43
  if spec == "defang":
28
44
  return defang(str(self))
29
45
  return str.__format__(str(self), spec)
30
46
 
31
- def _pack(self):
47
+ def _pack(self) -> int:
32
48
  return int(self.val)
33
49
 
34
50
  @staticmethod
35
- def _unpack(data):
51
+ def _unpack(data: int) -> ipaddress:
36
52
  return ipaddress(data)
37
53
 
38
54
 
@@ -40,17 +56,20 @@ class ipnetwork(FieldType):
40
56
  val = None
41
57
  _type = "net.ipnetwork"
42
58
 
43
- def __init__(self, addr):
59
+ def __init__(self, addr: str | int | bytes):
44
60
  self.val = ip_network(addr)
45
61
 
46
- def __eq__(self, b):
62
+ def __eq__(self, b: str | int | bytes | _IPNetwork) -> bool:
47
63
  try:
48
64
  return self.val == ip_network(b)
49
65
  except ValueError:
50
66
  return False
51
67
 
68
+ def __hash__(self) -> int:
69
+ return hash(self.val)
70
+
52
71
  @staticmethod
53
- def _is_subnet_of(a, b):
72
+ def _is_subnet_of(a: _IPNetwork, b: _IPNetwork) -> bool:
54
73
  try:
55
74
  # Always false if one is v4 and the other is v6.
56
75
  if a._version != b._version:
@@ -59,23 +78,23 @@ class ipnetwork(FieldType):
59
78
  except AttributeError:
60
79
  raise TypeError("Unable to test subnet containment " "between {} and {}".format(a, b))
61
80
 
62
- def __contains__(self, b):
81
+ def __contains__(self, b: str | int | bytes | _IPAddress) -> bool:
63
82
  try:
64
83
  return self._is_subnet_of(ip_network(b), self.val)
65
84
  except (ValueError, TypeError):
66
85
  return False
67
86
 
68
- def __str__(self):
87
+ def __str__(self) -> str:
69
88
  return str(self.val)
70
89
 
71
- def __repr__(self):
72
- return "{}({!r})".format(self._type, str(self))
90
+ def __repr__(self) -> str:
91
+ return f"{self._type}({str(self)!r})"
73
92
 
74
- def _pack(self):
93
+ def _pack(self) -> str:
75
94
  return self.val.compressed
76
95
 
77
96
  @staticmethod
78
- def _unpack(data):
97
+ def _unpack(data: str) -> ipnetwork:
79
98
  return ipnetwork(data)
80
99
 
81
100
 
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '3.17.dev5'
16
- __version_tuple__ = version_tuple = (3, 17, 'dev5')
15
+ __version__ = version = '3.17.dev7'
16
+ __version_tuple__ = version_tuple = (3, 17, 'dev7')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flow.record
3
- Version: 3.17.dev5
3
+ Version: 3.17.dev7
4
4
  Summary: A library for defining and creating structured data (called records) that can be streamed to disk or piped to other tools that use flow.record
5
5
  Author-email: Dissect Team <dissect@fox-it.com>
6
6
  License: Affero General Public License v3
@@ -16,12 +16,11 @@ Classifier: Operating System :: OS Independent
16
16
  Classifier: Programming Language :: Python :: 3
17
17
  Classifier: Topic :: Scientific/Engineering :: Information Analysis
18
18
  Classifier: Topic :: Utilities
19
- Requires-Python: ~=3.8
19
+ Requires-Python: ~=3.9
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
22
  License-File: COPYRIGHT
23
23
  Requires-Dist: msgpack>=0.5.2
24
- Requires-Dist: backports.zoneinfo[tzdata]; python_version < "3.9"
25
24
  Requires-Dist: tzdata; platform_system == "Windows"
26
25
  Provides-Extra: compression
27
26
  Requires-Dist: lz4; extra == "compression"
@@ -3,9 +3,6 @@ msgpack>=0.5.2
3
3
  [:platform_system == "Windows"]
4
4
  tzdata
5
5
 
6
- [:python_version < "3.9"]
7
- backports.zoneinfo[tzdata]
8
-
9
6
  [avro]
10
7
  fastavro[snappy]
11
8
 
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
  name = "flow.record"
7
7
  description = "A library for defining and creating structured data (called records) that can be streamed to disk or piped to other tools that use flow.record"
8
8
  readme = "README.md"
9
- requires-python = "~=3.8"
9
+ requires-python = "~=3.9"
10
10
  license.text = "Affero General Public License v3"
11
11
  authors = [
12
12
  {name = "Dissect Team", email = "dissect@fox-it.com"}
@@ -24,7 +24,6 @@ classifiers = [
24
24
  ]
25
25
  dependencies = [
26
26
  "msgpack>=0.5.2",
27
- "backports.zoneinfo[tzdata]; python_version<'3.9'",
28
27
  "tzdata; platform_system=='Windows'",
29
28
  ]
30
29
  dynamic = ["version"]
@@ -48,12 +48,19 @@ def test_record_ipaddress():
48
48
  assert TestRecord("0.0.0.0").ip == "0.0.0.0"
49
49
  assert TestRecord("192.168.0.1").ip == "192.168.0.1"
50
50
  assert TestRecord("255.255.255.255").ip == "255.255.255.255"
51
+ assert hash(TestRecord("192.168.0.1").ip) == hash(net.ipaddress("192.168.0.1"))
51
52
 
52
53
  # ipv6
53
54
  assert TestRecord("::1").ip == "::1"
54
55
  assert TestRecord("2001:4860:4860::8888").ip == "2001:4860:4860::8888"
55
56
  assert TestRecord("2001:4860:4860::4444").ip == "2001:4860:4860::4444"
56
57
 
58
+ # Test whether it functions in a set
59
+ data = {TestRecord(ip).ip for ip in ["192.168.0.1", "192.168.0.1", "::1", "::1"]}
60
+ assert len(data) == 2
61
+ assert net.ipaddress("::1") in data
62
+ assert net.ipaddress("192.168.0.1") in data
63
+
57
64
  # instantiate from different types
58
65
  assert TestRecord(1).ip == "0.0.0.1"
59
66
  assert TestRecord(0x7F0000FF).ip == "127.0.0.255"
@@ -90,6 +97,7 @@ def test_record_ipnetwork():
90
97
  assert "192.168.1.1" not in r.subnet
91
98
  assert isinstance(r.subnet, net.ipnetwork)
92
99
  assert repr(r.subnet) == "net.ipnetwork('192.168.0.0/24')"
100
+ assert hash(r.subnet) == hash(net.ipnetwork("192.168.0.0/24"))
93
101
 
94
102
  r = TestRecord("192.168.1.1/32")
95
103
  assert r.subnet == "192.168.1.1"
@@ -111,6 +119,13 @@ def test_record_ipnetwork():
111
119
  assert "64:ff9b::0.0.0.0" in r.subnet
112
120
  assert "64:ff9b::255.255.255.255" in r.subnet
113
121
 
122
+ # Test whether it functions in a set
123
+ data = {TestRecord(x).subnet for x in ["192.168.0.0/24", "192.168.0.0/24", "::1", "::1"]}
124
+ assert len(data) == 2
125
+ assert net.ipnetwork("::1") in data
126
+ assert net.ipnetwork("192.168.0.0/24") in data
127
+ assert "::1" not in data
128
+
114
129
 
115
130
  @pytest.mark.parametrize("PSelector", [Selector, CompiledSelector])
116
131
  def test_selector_ipaddress(PSelector):
@@ -50,7 +50,7 @@ deps =
50
50
  vermin
51
51
  commands =
52
52
  flake8 flow tests
53
- vermin -t=3.8- --no-tips --lint --exclude zoneinfo flow tests
53
+ vermin --target=3.9 --no-tips --lint flow tests
54
54
 
55
55
  [flake8]
56
56
  max-line-length = 120
File without changes