cloudquery-plugin-sdk 0.1.55__py3-none-any.whl

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 (57) hide show
  1. cloudquery/sdk/__init__.py +0 -0
  2. cloudquery/sdk/internal/__init__.py +0 -0
  3. cloudquery/sdk/internal/checkpoint.py +199 -0
  4. cloudquery/sdk/internal/memdb/__init__.py +1 -0
  5. cloudquery/sdk/internal/memdb/memdb.py +221 -0
  6. cloudquery/sdk/internal/servers/__init__.py +0 -0
  7. cloudquery/sdk/internal/servers/discovery_v1/__init__.py +0 -0
  8. cloudquery/sdk/internal/servers/discovery_v1/discovery.py +11 -0
  9. cloudquery/sdk/internal/servers/plugin_v3/__init__.py +1 -0
  10. cloudquery/sdk/internal/servers/plugin_v3/plugin.py +156 -0
  11. cloudquery/sdk/message/__init__.py +14 -0
  12. cloudquery/sdk/message/read.py +6 -0
  13. cloudquery/sdk/message/sync.py +31 -0
  14. cloudquery/sdk/message/write.py +24 -0
  15. cloudquery/sdk/plugin/__init__.py +1 -0
  16. cloudquery/sdk/plugin/plugin.py +102 -0
  17. cloudquery/sdk/py.typed +0 -0
  18. cloudquery/sdk/scalar/__init__.py +15 -0
  19. cloudquery/sdk/scalar/binary.py +35 -0
  20. cloudquery/sdk/scalar/bool.py +48 -0
  21. cloudquery/sdk/scalar/date32.py +39 -0
  22. cloudquery/sdk/scalar/date64.py +39 -0
  23. cloudquery/sdk/scalar/float.py +49 -0
  24. cloudquery/sdk/scalar/int.py +56 -0
  25. cloudquery/sdk/scalar/json.py +27 -0
  26. cloudquery/sdk/scalar/list.py +56 -0
  27. cloudquery/sdk/scalar/scalar.py +30 -0
  28. cloudquery/sdk/scalar/scalar_factory.py +64 -0
  29. cloudquery/sdk/scalar/string.py +31 -0
  30. cloudquery/sdk/scalar/timestamp.py +41 -0
  31. cloudquery/sdk/scalar/uint.py +58 -0
  32. cloudquery/sdk/scalar/uuid.py +43 -0
  33. cloudquery/sdk/scalar/vector.py +43 -0
  34. cloudquery/sdk/scheduler/__init__.py +3 -0
  35. cloudquery/sdk/scheduler/scheduler.py +267 -0
  36. cloudquery/sdk/scheduler/table_resolver.py +48 -0
  37. cloudquery/sdk/schema/__init__.py +16 -0
  38. cloudquery/sdk/schema/arrow.py +11 -0
  39. cloudquery/sdk/schema/column.py +77 -0
  40. cloudquery/sdk/schema/resource.py +29 -0
  41. cloudquery/sdk/schema/table.py +332 -0
  42. cloudquery/sdk/serve/__init__.py +1 -0
  43. cloudquery/sdk/serve/plugin.py +407 -0
  44. cloudquery/sdk/stateclient/__init__.py +1 -0
  45. cloudquery/sdk/stateclient/keys.py +44 -0
  46. cloudquery/sdk/stateclient/stateclient.py +278 -0
  47. cloudquery/sdk/transformers/__init__.py +2 -0
  48. cloudquery/sdk/transformers/openapi.py +49 -0
  49. cloudquery/sdk/transformers/transformers.py +13 -0
  50. cloudquery/sdk/types/__init__.py +2 -0
  51. cloudquery/sdk/types/json.py +26 -0
  52. cloudquery/sdk/types/uuid.py +28 -0
  53. cloudquery_plugin_sdk-0.1.55.dist-info/METADATA +50 -0
  54. cloudquery_plugin_sdk-0.1.55.dist-info/RECORD +57 -0
  55. cloudquery_plugin_sdk-0.1.55.dist-info/WHEEL +5 -0
  56. cloudquery_plugin_sdk-0.1.55.dist-info/licenses/LICENSE +353 -0
  57. cloudquery_plugin_sdk-0.1.55.dist-info/top_level.txt +1 -0
@@ -0,0 +1,102 @@
1
+ from dataclasses import dataclass
2
+ from typing import List, Generator
3
+
4
+ from cloudquery.sdk import message
5
+ from cloudquery.sdk.schema import Table
6
+
7
+ MIGRATE_MODE_STRINGS = ["safe", "force"]
8
+
9
+
10
+ @dataclass
11
+ class TableOptions:
12
+ tables: List[str] = None
13
+ skip_tables: List[str] = None
14
+ skip_dependent_tables: bool = False
15
+
16
+
17
+ @dataclass
18
+ class BackendOptions:
19
+ connection: str = None
20
+ table_name: str = None
21
+ # set when the CLI persists state sent as checkpoints on the sync stream
22
+ supports_checkpoints: bool = False
23
+
24
+
25
+ @dataclass
26
+ class SyncOptions:
27
+ deterministic_cq_id: bool = False
28
+ skip_dependent_tables: bool = False
29
+ skip_tables: List[str] = None
30
+ tables: List[str] = None
31
+ backend_options: BackendOptions = None
32
+
33
+
34
+ @dataclass
35
+ class BuildTarget:
36
+ os: str = None
37
+ arch: str = None
38
+
39
+
40
+ @dataclass
41
+ class Options:
42
+ dockerfile: str = None
43
+ build_targets: List[BuildTarget] = None
44
+ team: str = None
45
+ kind: str = None
46
+ json_schema: str = None
47
+
48
+
49
+ class Plugin:
50
+ def __init__(self, name: str, version: str, opts: Options = None) -> None:
51
+ self._name = name
52
+ self._version = version
53
+ self._opts = Options() if opts is None else opts
54
+ if self._opts.dockerfile is None:
55
+ self._opts.dockerfile = "Dockerfile"
56
+ if self._opts.build_targets is None:
57
+ self._opts.build_targets = [
58
+ BuildTarget("linux", "amd64"),
59
+ BuildTarget("linux", "arm64"),
60
+ ]
61
+
62
+ def init(self, spec: bytes, no_connection: bool = False) -> None:
63
+ pass
64
+
65
+ def set_logger(self, logger) -> None:
66
+ pass
67
+
68
+ def name(self) -> str:
69
+ return self._name
70
+
71
+ def version(self) -> str:
72
+ return self._version
73
+
74
+ def team(self) -> str:
75
+ return self._opts.team
76
+
77
+ def kind(self) -> str:
78
+ return self._opts.kind
79
+
80
+ def json_schema(self) -> str:
81
+ return self._opts.json_schema
82
+
83
+ def dockerfile(self) -> str:
84
+ return self._opts.dockerfile
85
+
86
+ def build_targets(self) -> List[BuildTarget]:
87
+ return self._opts.build_targets
88
+
89
+ def get_tables(self, options: TableOptions) -> List[Table]:
90
+ raise NotImplementedError()
91
+
92
+ def sync(self, options: SyncOptions) -> Generator[message.SyncMessage, None, None]:
93
+ raise NotImplementedError()
94
+
95
+ def write(self, writer: Generator[message.WriteMessage, None, None]) -> None:
96
+ raise NotImplementedError()
97
+
98
+ def read(self, table: Table) -> Generator[message.ReadMessage, None, None]:
99
+ raise NotImplementedError()
100
+
101
+ def close(self) -> None:
102
+ raise NotImplementedError()
File without changes
@@ -0,0 +1,15 @@
1
+ from .scalar import Scalar, ScalarInvalidTypeError, NULL_VALUE
2
+ from .scalar_factory import ScalarFactory
3
+ from .vector import Vector
4
+
5
+ from .binary import Binary
6
+ from .bool import Bool
7
+ from .date32 import Date32
8
+ from .date64 import Date64
9
+ from .float import Float
10
+ from .int import Int
11
+ from .list import List
12
+ from .string import String
13
+ from .timestamp import Timestamp
14
+ from .uint import Uint
15
+ from .uuid import UUID
@@ -0,0 +1,35 @@
1
+ from cloudquery.sdk.scalar import Scalar, ScalarInvalidTypeError
2
+ from .scalar import NULL_VALUE
3
+
4
+
5
+ class Binary(Scalar):
6
+ def __eq__(self, scalar: Scalar) -> bool:
7
+ if scalar is None:
8
+ return False
9
+ if isinstance(scalar, Binary):
10
+ return self._value == scalar._value and self._valid == scalar._valid
11
+ return False
12
+
13
+ @property
14
+ def value(self):
15
+ return self._value
16
+
17
+ def set(self, value: any):
18
+ if value is None:
19
+ return
20
+
21
+ if isinstance(value, Binary):
22
+ self._valid = value.is_valid
23
+ self._value = value.value
24
+ return
25
+
26
+ if isinstance(value, bytes):
27
+ self._valid = True
28
+ self._value = value
29
+ elif isinstance(value, str):
30
+ self._valid = True
31
+ self._value = value.encode()
32
+ else:
33
+ raise ScalarInvalidTypeError(
34
+ f"Invalid type {type(value)} for Binary scalar"
35
+ )
@@ -0,0 +1,48 @@
1
+ from cloudquery.sdk.scalar import Scalar, ScalarInvalidTypeError, NULL_VALUE
2
+ from typing import Any
3
+
4
+
5
+ def parse_string_to_bool(input_string):
6
+ true_strings = ["true", "t", "yes", "y", "1"]
7
+ false_strings = ["false", "f", "no", "n", "0"]
8
+
9
+ lower_input = input_string.lower()
10
+
11
+ if lower_input in true_strings:
12
+ return True
13
+ if lower_input in false_strings:
14
+ return False
15
+ else:
16
+ raise ScalarInvalidTypeError(f"Invalid boolean string: {input_string}")
17
+
18
+
19
+ class Bool(Scalar):
20
+ def __eq__(self, scalar: Scalar) -> bool:
21
+ if scalar is None:
22
+ return False
23
+ if isinstance(scalar, Bool):
24
+ return self._value == scalar._value and self._valid == scalar._valid
25
+ return False
26
+
27
+ @property
28
+ def value(self):
29
+ return self._value
30
+
31
+ def set(self, value: Any):
32
+ if value is None:
33
+ self._valid = False
34
+ return
35
+
36
+ if isinstance(value, Bool):
37
+ self._valid = value.is_valid
38
+ self._value = value.value
39
+ return
40
+
41
+ if isinstance(value, bool):
42
+ self._value = value
43
+ elif isinstance(value, str):
44
+ self._value = parse_string_to_bool(value)
45
+ else:
46
+ raise ScalarInvalidTypeError(f"Invalid type {type(value)} for Bool scalar")
47
+
48
+ self._valid = True
@@ -0,0 +1,39 @@
1
+ from cloudquery.sdk.scalar import Scalar, ScalarInvalidTypeError, NULL_VALUE
2
+ from datetime import datetime, time
3
+ from typing import Any
4
+
5
+
6
+ class Date32(Scalar):
7
+ def __eq__(self, scalar: Scalar) -> bool:
8
+ if scalar is None:
9
+ return False
10
+ if isinstance(scalar, Date32):
11
+ return self._value == scalar._value and self._valid == scalar._valid
12
+ return False
13
+
14
+ @property
15
+ def value(self):
16
+ return self._value
17
+
18
+ def set(self, value: Any):
19
+ if value is None:
20
+ self._valid = False
21
+ return
22
+
23
+ if isinstance(value, Date32):
24
+ self._valid = value.is_valid
25
+ self._value = value.value
26
+ return
27
+
28
+ if isinstance(value, datetime):
29
+ self._value = value
30
+ elif isinstance(value, str):
31
+ self._value = datetime.strptime(value, "%Y-%m-%d")
32
+ elif isinstance(value, time):
33
+ self._value = datetime.combine(datetime.today(), value)
34
+ else:
35
+ raise ScalarInvalidTypeError(
36
+ f"Invalid type {type(value)} for Date32 scalar"
37
+ )
38
+
39
+ self._valid = True
@@ -0,0 +1,39 @@
1
+ from cloudquery.sdk.scalar import Scalar, ScalarInvalidTypeError, NULL_VALUE
2
+ from datetime import datetime, time
3
+ from typing import Any
4
+
5
+
6
+ class Date64(Scalar):
7
+ def __eq__(self, scalar: Scalar) -> bool:
8
+ if scalar is None:
9
+ return False
10
+ if isinstance(scalar, Date64):
11
+ return self._value == scalar._value and self._valid == scalar._valid
12
+ return False
13
+
14
+ @property
15
+ def value(self):
16
+ return self._value
17
+
18
+ def set(self, value: Any):
19
+ if value is None:
20
+ self._valid = False
21
+ return
22
+
23
+ if isinstance(value, Date64):
24
+ self._valid = value.is_valid
25
+ self._value = value.value
26
+ return
27
+
28
+ if isinstance(value, datetime):
29
+ self._value = value
30
+ elif isinstance(value, str):
31
+ self._value = datetime.strptime(value, "%Y-%m-%d")
32
+ elif isinstance(value, time):
33
+ self._value = datetime.combine(datetime.today(), value)
34
+ else:
35
+ raise ScalarInvalidTypeError(
36
+ f"Invalid type {type(value)} for Date64 scalar"
37
+ )
38
+
39
+ self._valid = True
@@ -0,0 +1,49 @@
1
+ from cloudquery.sdk.scalar import Scalar, ScalarInvalidTypeError
2
+
3
+
4
+ class Float(Scalar):
5
+ def __init__(self, valid: bool = False, value: any = None, bitwidth: int = 64):
6
+ super().__init__(valid, value)
7
+ self._bitwidth = bitwidth
8
+
9
+ def __eq__(self, scalar: Scalar) -> bool:
10
+ if scalar is None:
11
+ return False
12
+ if isinstance(scalar, Float) and self._bitwidth == scalar.bitwidth:
13
+ return self._value == scalar._value and self._valid == scalar._valid
14
+ return False
15
+
16
+ @property
17
+ def bitwidth(self):
18
+ return self._bitwidth
19
+
20
+ @property
21
+ def value(self):
22
+ return self._value
23
+
24
+ def set(self, value: any):
25
+ if value is None:
26
+ self._valid = False
27
+ return
28
+
29
+ if isinstance(value, Float) and value.bitwidth == self._bitwidth:
30
+ self._valid = value.is_valid
31
+ self._value = value.value
32
+ return
33
+
34
+ if isinstance(value, int):
35
+ self._value = float(value)
36
+ elif isinstance(value, float):
37
+ self._value = value
38
+ elif isinstance(value, str):
39
+ try:
40
+ self._value = float(value)
41
+ except ValueError as e:
42
+ raise ScalarInvalidTypeError(
43
+ f"Invalid value for Float{self._bitwidth} scalar"
44
+ ) from e
45
+ else:
46
+ raise ScalarInvalidTypeError(
47
+ f"Invalid type {type(value)} for Float{self._bitwidth} scalar"
48
+ )
49
+ self._valid = True
@@ -0,0 +1,56 @@
1
+ from cloudquery.sdk.scalar import Scalar, ScalarInvalidTypeError
2
+
3
+
4
+ class Int(Scalar):
5
+ def __init__(self, valid: bool = False, value: any = None, bitwidth: int = 64):
6
+ self._bitwidth = bitwidth
7
+ self._min = -(2 ** (bitwidth - 1))
8
+ self._max = 2 ** (bitwidth - 1)
9
+ super().__init__(valid, value)
10
+
11
+ def __eq__(self, scalar: Scalar) -> bool:
12
+ if scalar is None:
13
+ return False
14
+ if isinstance(scalar, Int) and self._bitwidth == scalar.bitwidth:
15
+ return self._value == scalar._value and self._valid == scalar._valid
16
+ return False
17
+
18
+ @property
19
+ def bitwidth(self):
20
+ return self._bitwidth
21
+
22
+ @property
23
+ def value(self):
24
+ return self._value
25
+
26
+ def set(self, value: any):
27
+ if value is None:
28
+ self._valid = False
29
+ return
30
+
31
+ if isinstance(value, Int) and value.bitwidth == self._bitwidth:
32
+ self._valid = value.is_valid
33
+ self._value = value.value
34
+ return
35
+
36
+ if isinstance(value, int):
37
+ val = value
38
+ elif isinstance(value, float):
39
+ val = int(value)
40
+ elif isinstance(value, str):
41
+ try:
42
+ val = int(value)
43
+ except ValueError as e:
44
+ raise ScalarInvalidTypeError(
45
+ f"Invalid type for Int{self._bitwidth} scalar"
46
+ ) from e
47
+ else:
48
+ raise ScalarInvalidTypeError(
49
+ f"Invalid type {type(value)} for Int{self._bitwidth} scalar"
50
+ )
51
+ if val < self._min or val >= self._max:
52
+ raise ScalarInvalidTypeError(
53
+ f"Invalid Int{self._bitwidth} scalar with value {val}"
54
+ )
55
+ self._value = val
56
+ self._valid = True
@@ -0,0 +1,27 @@
1
+ import json
2
+ from cloudquery.sdk.scalar import Scalar, ScalarInvalidTypeError
3
+
4
+
5
+ class JSON(Scalar):
6
+ def __eq__(self, scalar: Scalar) -> bool:
7
+ if scalar is None:
8
+ return False
9
+ if isinstance(scalar, JSON):
10
+ return self._value == scalar._value and self._valid == scalar._valid
11
+ return False
12
+
13
+ @property
14
+ def value(self):
15
+ return self._value
16
+
17
+ def set(self, value: any):
18
+ if value is None:
19
+ return
20
+
21
+ if isinstance(value, (str, bytes)):
22
+ # test if it is a valid json
23
+ json.loads(value)
24
+ self._value = value
25
+ else:
26
+ self._value = json.dumps(value)
27
+ self._valid = True
@@ -0,0 +1,56 @@
1
+ from cloudquery.sdk.scalar import Scalar, ScalarInvalidTypeError
2
+ from .scalar import NULL_VALUE
3
+ from .vector import Vector
4
+ from typing import Any, Type
5
+
6
+
7
+ class List(Scalar):
8
+ def __init__(self, scalar_type: Type[Scalar]):
9
+ super().__init__(False, None)
10
+ self._value = Vector(scalar_type)
11
+ self._type = scalar_type
12
+
13
+ def __eq__(self, other: "List") -> bool:
14
+ if (not isinstance(other, self.__class__)) or self._valid != other._valid:
15
+ return False
16
+ return self._value == other._value
17
+
18
+ @property
19
+ def type(self):
20
+ return self._type
21
+
22
+ @property
23
+ def value(self):
24
+ return self._value
25
+
26
+ def set(self, value: Any):
27
+ if value is None:
28
+ self._valid = False
29
+ self._value = Vector()
30
+ return
31
+
32
+ if isinstance(value, self._type):
33
+ if not value.is_valid:
34
+ self._valid = False
35
+ self._value = Vector()
36
+ return
37
+ return self.set([value.value])
38
+
39
+ if isinstance(value, (list, tuple)):
40
+ self._value = Vector()
41
+ for item in value:
42
+ scalar = self._type()
43
+ scalar.set(item)
44
+ self._value.append(scalar)
45
+ self._valid = True
46
+ return
47
+
48
+ raise ScalarInvalidTypeError(f"Invalid type {type(value)} for List")
49
+
50
+ def __str__(self) -> str:
51
+ if not self._valid:
52
+ return NULL_VALUE
53
+ return f"[{', '.join(str(v) for v in self._value)}]"
54
+
55
+ def __len__(self):
56
+ return len(self.value.data)
@@ -0,0 +1,30 @@
1
+ from abc import abstractmethod
2
+
3
+ NULL_VALUE = "null"
4
+
5
+
6
+ class ScalarInvalidTypeError(Exception):
7
+ pass
8
+
9
+
10
+ class Scalar:
11
+ def __init__(self, valid: bool = False, value: any = None):
12
+ self._valid = valid
13
+ self._value = None
14
+ self.set(value)
15
+
16
+ @property
17
+ def is_valid(self) -> bool:
18
+ return self._valid
19
+
20
+ def __str__(self) -> str:
21
+ return str(self._value) if self._valid else NULL_VALUE
22
+
23
+ @property
24
+ @abstractmethod
25
+ def value(self):
26
+ pass
27
+
28
+ @abstractmethod
29
+ def set(self, value: any):
30
+ pass
@@ -0,0 +1,64 @@
1
+ from functools import partial
2
+
3
+ import pyarrow as pa
4
+
5
+ from cloudquery.sdk.types import UUIDType, JSONType
6
+ from .binary import Binary
7
+ from .bool import Bool
8
+ from .date32 import Date32
9
+ from .date64 import Date64
10
+ from .float import Float
11
+ from .int import Int
12
+ from .json import JSON
13
+ from .list import List
14
+ from .scalar import ScalarInvalidTypeError
15
+ from .string import String
16
+ from .timestamp import Timestamp
17
+ from .uint import Uint
18
+ from .uuid import UUID
19
+
20
+
21
+ class ScalarFactory:
22
+ def __init__(self):
23
+ pass
24
+
25
+ def new_scalar(self, dt: pa.DataType):
26
+ dt_id = dt.id
27
+ type_id__map = {
28
+ pa.types.lib.Type_INT64: partial(Int, bitwidth=64),
29
+ pa.types.lib.Type_INT32: partial(Int, bitwidth=32),
30
+ pa.types.lib.Type_INT16: partial(Int, bitwidth=16),
31
+ pa.types.lib.Type_INT8: partial(Int, bitwidth=8),
32
+ pa.types.lib.Type_UINT64: partial(Uint, bitwidth=64),
33
+ pa.types.lib.Type_UINT32: partial(Uint, bitwidth=32),
34
+ pa.types.lib.Type_UINT16: partial(Uint, bitwidth=16),
35
+ pa.types.lib.Type_UINT8: partial(Uint, bitwidth=8),
36
+ pa.types.lib.Type_BINARY: Binary,
37
+ pa.types.lib.Type_LARGE_BINARY: Binary,
38
+ pa.types.lib.Type_FIXED_SIZE_BINARY: Binary,
39
+ pa.types.lib.Type_BOOL: Bool,
40
+ pa.types.lib.Type_DATE64: Date64,
41
+ pa.types.lib.Type_DATE32: Date32,
42
+ pa.types.lib.Type_DOUBLE: partial(Float, bitwidth=64),
43
+ pa.types.lib.Type_FLOAT: partial(Float, bitwidth=32),
44
+ pa.types.lib.Type_HALF_FLOAT: partial(Float, bitwidth=16),
45
+ pa.types.lib.Type_LIST: List,
46
+ pa.types.lib.Type_LARGE_LIST: List,
47
+ pa.types.lib.Type_FIXED_SIZE_LIST: List,
48
+ pa.types.lib.Type_STRING: String,
49
+ pa.types.lib.Type_LARGE_STRING: String,
50
+ pa.types.lib.Type_TIMESTAMP: Timestamp,
51
+ }
52
+ # Built-in Types
53
+ if dt_id in type_id__map:
54
+ scalar_type = type_id__map[dt_id]
55
+ if scalar_type == List:
56
+ item = self.new_scalar(dt.field(0).type)
57
+ return scalar_type(type(item))
58
+ return scalar_type()
59
+ # Extension Types - Can't do the same trick as above as they don't have `id`s and they are not hashable. :(
60
+ if dt == UUIDType():
61
+ return UUID()
62
+ if dt == JSONType():
63
+ return JSON()
64
+ raise ScalarInvalidTypeError(f"Invalid type {dt} for scalar")
@@ -0,0 +1,31 @@
1
+ from cloudquery.sdk.scalar import Scalar, ScalarInvalidTypeError
2
+
3
+
4
+ class String(Scalar):
5
+ def __eq__(self, scalar: Scalar) -> bool:
6
+ if scalar is None:
7
+ return False
8
+ if isinstance(scalar, String):
9
+ return self._value == scalar._value and self._valid == scalar._valid
10
+ return False
11
+
12
+ @property
13
+ def value(self):
14
+ return self._value
15
+
16
+ def set(self, value: any):
17
+ if value is None:
18
+ return
19
+
20
+ if isinstance(value, String):
21
+ self._valid = value._valid
22
+ self._value = value.value
23
+ return
24
+
25
+ if isinstance(value, str):
26
+ self._valid = True
27
+ self._value = value
28
+ else:
29
+ raise ScalarInvalidTypeError(
30
+ f"Invalid type {type(value)} for String scalar"
31
+ )
@@ -0,0 +1,41 @@
1
+ from cloudquery.sdk.scalar import Scalar, ScalarInvalidTypeError, NULL_VALUE
2
+ from datetime import datetime, time
3
+ from typing import Any
4
+ import pandas as pd
5
+
6
+
7
+ class Timestamp(Scalar):
8
+ def __eq__(self, scalar: Scalar) -> bool:
9
+ if scalar is None:
10
+ return False
11
+ if isinstance(scalar, Timestamp):
12
+ return self._value == scalar._value and self._valid == scalar._valid
13
+ return False
14
+
15
+ @property
16
+ def value(self):
17
+ return self._value
18
+
19
+ def set(self, value: Any):
20
+ if value is None:
21
+ return
22
+
23
+ if isinstance(value, Timestamp):
24
+ self._valid = value.is_valid
25
+ self._value = value.value
26
+ return
27
+
28
+ if isinstance(value, pd.Timestamp):
29
+ self._value = value
30
+ elif isinstance(value, datetime):
31
+ self._value = pd.to_datetime(value)
32
+ elif isinstance(value, str):
33
+ self._value = pd.to_datetime(value)
34
+ elif isinstance(value, time):
35
+ self._value = pd.to_datetime(datetime.combine(datetime.today(), value))
36
+ else:
37
+ raise ScalarInvalidTypeError(
38
+ f"Invalid type {type(value)} for Timestamp scalar"
39
+ )
40
+
41
+ self._valid = True