Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions cognite/extractorutils/unstable/configuration/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,128 @@ def _log_handler_default() -> list[LogHandlerConfig]:
return [LogConsoleHandlerConfig(type="console", level=LogLevel.INFO)]


class FileSizeConfig(ConfigModel):
"""
Configuration parameter for setting a file size.
"""

expression: str

@staticmethod
def _parse_size_in_bytes(v: str) -> int:
sizes = {
"kb": 1000,
"mb": 1_000_000,
"gb": 1_000_000_000,
"tb": 1_000_000_000_000,
"kib": 1024,
"mib": 1_048_576,
"gib": 1_073_741_824,
"tib": 1_099_511_627_776,
}
try:
return int(v)
except ValueError:
pass
v_lower = v.lower().replace(" ", "")
for size in sizes:
if v_lower.endswith(size):
num = float(v_lower.replace(size, ""))
return int(num * sizes[size])
raise InvalidConfigError(f"Invalid unit for file size: {v}. Valid units: {sizes.keys()}")

@property
def _bytes(self) -> int:
return self._parse_size_in_bytes(self.expression)

@property
def bytes(self) -> int:
"""
File size in bytes.
"""
return self._bytes

@property
def kilobytes(self) -> float:
"""
File size in kilobytes.
"""
return self._bytes / 1000

@property
def megabytes(self) -> float:
"""
File size in megabytes.
"""
return self._bytes / 1_000_000

@property
def gigabytes(self) -> float:
"""
File size in gigabytes.
"""
return self._bytes / 1_000_000_000

@property
def terabytes(self) -> float:
"""
File size in terabytes.
"""
return self._bytes / 1_000_000_000_000

@property
def kibibytes(self) -> float:
"""
File size in kibibytes (1024 bytes).
"""
return self._bytes / 1024

@property
def mebibytes(self) -> float:
"""
File size in mebibytes (1024 kibibytes).
"""
return self._bytes / 1_048_576

@property
def gibibytes(self) -> float:
"""
File size in gibibytes (1024 mebibytes).
"""
return self._bytes / 1_073_741_824

@property
def tebibytes(self) -> float:
"""
File size in tebibytes (1024 gibibytes).
"""
return self._bytes / 1_099_511_627_776

def __int__(self) -> int:
"""
Returns the file size as bytes.
"""
return int(self._bytes)

def __float__(self) -> float:
"""
Returns the file size as bytes.
"""
return float(self._bytes)

def __str__(self) -> str:
"""
Returns the file size as a human readable string.
"""
return self.expression

def __repr__(self) -> str:
"""
Returns the file size as a human readable string.
"""
return self.expression


class RawDestinationConfig(ConfigModel):
"""
Configuration parameters for using Raw.
Expand Down
15 changes: 15 additions & 0 deletions tests/test_unstable/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from cognite.extractorutils.unstable.configuration.loaders import ConfigFormat, load_io
from cognite.extractorutils.unstable.configuration.models import (
ConnectionConfig,
FileSizeConfig,
TimeIntervalConfig,
_ClientCredentialsConfig,
)
Expand Down Expand Up @@ -212,3 +213,17 @@ def test_from_env() -> None:

# Check that the produces cogniteclient object is valid
assert len(client.assets.list(limit=1)) == 1


def test_parse_file_size() -> None:
assert FileSizeConfig(expression="154584").bytes == 154584
assert FileSizeConfig(expression="1kB").bytes == 1000
assert FileSizeConfig(expression="25MB").bytes == 25000000
assert FileSizeConfig(expression="1kib").bytes == 1024
assert FileSizeConfig(expression="2.7MiB").bytes == 2831155
assert FileSizeConfig(expression="4 KB").bytes == 4000

assert FileSizeConfig(expression="4 KB").kilobytes == pytest.approx(4)
assert FileSizeConfig(expression="453 kB").megabytes == pytest.approx(0.453)
assert FileSizeConfig(expression="1543 kiB").kilobytes == pytest.approx(1580.032)
assert FileSizeConfig(expression="14.5 mb").kilobytes == pytest.approx(14500)
Loading