cloudquery-plugin-sdk 0.1.46__tar.gz → 0.1.48__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 (63) hide show
  1. {cloudquery_plugin_sdk-0.1.46/cloudquery_plugin_sdk.egg-info → cloudquery_plugin_sdk-0.1.48}/PKG-INFO +8 -8
  2. cloudquery_plugin_sdk-0.1.48/cloudquery/sdk/internal/memdb/memdb.py +221 -0
  3. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/internal/servers/plugin_v3/plugin.py +7 -0
  4. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/message/__init__.py +6 -1
  5. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/message/sync.py +6 -0
  6. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scheduler/scheduler.py +2 -0
  7. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48/cloudquery_plugin_sdk.egg-info}/PKG-INFO +8 -8
  8. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery_plugin_sdk.egg-info/requires.txt +7 -7
  9. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/setup.py +8 -8
  10. cloudquery_plugin_sdk-0.1.46/cloudquery/sdk/internal/memdb/memdb.py +0 -118
  11. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/LICENSE +0 -0
  12. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/README.md +0 -0
  13. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/__init__.py +0 -0
  14. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/internal/__init__.py +0 -0
  15. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/internal/memdb/__init__.py +0 -0
  16. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/internal/servers/__init__.py +0 -0
  17. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/internal/servers/discovery_v1/__init__.py +0 -0
  18. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/internal/servers/discovery_v1/discovery.py +0 -0
  19. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/internal/servers/plugin_v3/__init__.py +0 -0
  20. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/message/read.py +0 -0
  21. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/message/write.py +0 -0
  22. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/plugin/__init__.py +0 -0
  23. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/plugin/plugin.py +0 -0
  24. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/py.typed +0 -0
  25. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scalar/__init__.py +0 -0
  26. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scalar/binary.py +0 -0
  27. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scalar/bool.py +0 -0
  28. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scalar/date32.py +0 -0
  29. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scalar/date64.py +0 -0
  30. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scalar/float.py +0 -0
  31. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scalar/int.py +0 -0
  32. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scalar/json.py +0 -0
  33. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scalar/list.py +0 -0
  34. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scalar/scalar.py +0 -0
  35. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scalar/scalar_factory.py +0 -0
  36. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scalar/string.py +0 -0
  37. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scalar/timestamp.py +0 -0
  38. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scalar/uint.py +0 -0
  39. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scalar/uuid.py +0 -0
  40. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scalar/vector.py +0 -0
  41. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scheduler/__init__.py +0 -0
  42. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/scheduler/table_resolver.py +0 -0
  43. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/schema/__init__.py +0 -0
  44. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/schema/arrow.py +0 -0
  45. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/schema/column.py +0 -0
  46. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/schema/resource.py +0 -0
  47. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/schema/table.py +0 -0
  48. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/serve/__init__.py +0 -0
  49. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/serve/plugin.py +0 -0
  50. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/stateclient/__init__.py +0 -0
  51. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/stateclient/stateclient.py +0 -0
  52. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/transformers/__init__.py +0 -0
  53. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/transformers/openapi.py +0 -0
  54. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/transformers/transformers.py +0 -0
  55. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/types/__init__.py +0 -0
  56. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/types/json.py +0 -0
  57. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery/sdk/types/uuid.py +0 -0
  58. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery_plugin_sdk.egg-info/SOURCES.txt +0 -0
  59. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery_plugin_sdk.egg-info/dependency_links.txt +0 -0
  60. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery_plugin_sdk.egg-info/namespace_packages.txt +0 -0
  61. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery_plugin_sdk.egg-info/not-zip-safe +0 -0
  62. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/cloudquery_plugin_sdk.egg-info/top_level.txt +0 -0
  63. {cloudquery_plugin_sdk-0.1.46 → cloudquery_plugin_sdk-0.1.48}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudquery-plugin-sdk
3
- Version: 0.1.46
3
+ Version: 0.1.48
4
4
  Summary: CloudQuery Plugin SDK for Python
5
5
  Home-page: https://github.com/cloudquery/plugin-sdk-python
6
6
  Author: CloudQuery LTD
@@ -20,25 +20,25 @@ Classifier: Operating System :: OS Independent
20
20
  Classifier: Topic :: Internet
21
21
  Requires-Python: >=3.7
22
22
  License-File: LICENSE
23
- Requires-Dist: cloudquery-plugin-pb==0.0.46
23
+ Requires-Dist: cloudquery-plugin-pb==0.0.47
24
24
  Requires-Dist: exceptiongroup==1.3.0
25
- Requires-Dist: black==25.1.0
26
- Requires-Dist: grpcio==1.74.0
27
- Requires-Dist: grpcio-tools==1.74.0
25
+ Requires-Dist: black==25.9.0
26
+ Requires-Dist: grpcio==1.75.0
27
+ Requires-Dist: grpcio-tools==1.75.0
28
28
  Requires-Dist: iniconfig==2.1.0
29
29
  Requires-Dist: Jinja2==3.1.6
30
30
  Requires-Dist: MarkupSafe==3.0.2
31
- Requires-Dist: numpy==2.3.2
31
+ Requires-Dist: numpy==2.3.3
32
32
  Requires-Dist: packaging==24.2
33
33
  Requires-Dist: pandas==2.3.2
34
34
  Requires-Dist: pluggy==1.6.0
35
35
  Requires-Dist: protobuf>=6.31.1
36
36
  Requires-Dist: pyarrow==19.0.1
37
- Requires-Dist: pytest==8.4.1
37
+ Requires-Dist: pytest==8.4.2
38
38
  Requires-Dist: python-dateutil>=2.8.1
39
39
  Requires-Dist: pytz==2025.2
40
40
  Requires-Dist: six==1.17.0
41
- Requires-Dist: structlog==25.1.0
41
+ Requires-Dist: structlog==25.4.0
42
42
  Requires-Dist: tomli==2.2.1
43
43
  Requires-Dist: tzdata==2025.1
44
44
  Dynamic: author
@@ -0,0 +1,221 @@
1
+ import json
2
+
3
+ from cloudquery.sdk import plugin
4
+ from cloudquery.sdk import message
5
+ from cloudquery.sdk import schema
6
+ from cloudquery.sdk.scheduler import Scheduler, TableResolver
7
+ from typing import List, Generator, Dict, Any
8
+ import pyarrow as pa
9
+ from cloudquery.sdk.schema.table import Table
10
+ from cloudquery.sdk.schema.arrow import METADATA_TABLE_NAME
11
+ from cloudquery.sdk.types import JSONType
12
+ from dataclasses import dataclass, field
13
+
14
+ NAME = "memdb"
15
+ VERSION = "development"
16
+
17
+
18
+ class Client:
19
+ def __init__(self) -> None:
20
+ pass
21
+
22
+ def id(self):
23
+ return "memdb"
24
+
25
+
26
+ class MemDBResolver(TableResolver):
27
+ def __init__(
28
+ self, table: Table, records: List, child_resolvers: list[TableResolver] = None
29
+ ) -> None:
30
+ super().__init__(table=table, child_resolvers=child_resolvers)
31
+ self._records = records
32
+
33
+ def resolve(self, client: None, parent_resource) -> Generator[Any, None, None]:
34
+ for record in self._records:
35
+ yield record
36
+
37
+
38
+ class Table1Relation1(Table):
39
+ def __init__(self) -> None:
40
+ super().__init__(
41
+ name="table_1_relation_1",
42
+ columns=[
43
+ schema.Column(
44
+ name="name",
45
+ type=pa.string(),
46
+ primary_key=True,
47
+ not_null=True,
48
+ unique=True,
49
+ ),
50
+ schema.Column(name="data", type=JSONType()),
51
+ ],
52
+ title="Table 1 Relation 1",
53
+ description="Test Table 1 Relation 1",
54
+ )
55
+
56
+ @property
57
+ def resolver(self):
58
+ return MemDBResolver(
59
+ self,
60
+ records=[
61
+ {"name": "a", "data": {"a": 1}},
62
+ {"name": "b", "data": {"b": 2}},
63
+ {"name": "c", "data": {"c": 3}},
64
+ ],
65
+ )
66
+
67
+
68
+ class Table1(Table):
69
+ def __init__(self) -> None:
70
+ super().__init__(
71
+ name="table_1",
72
+ columns=[
73
+ schema.Column(
74
+ name="name",
75
+ type=pa.string(),
76
+ primary_key=True,
77
+ not_null=True,
78
+ unique=True,
79
+ ),
80
+ schema.Column(
81
+ name="id",
82
+ type=pa.int64(),
83
+ primary_key=True,
84
+ not_null=True,
85
+ unique=True,
86
+ incremental_key=True,
87
+ ),
88
+ ],
89
+ title="Table 1",
90
+ description="Test Table 1",
91
+ is_incremental=True,
92
+ relations=[Table1Relation1()],
93
+ )
94
+
95
+ @property
96
+ def resolver(self):
97
+ child_resolvers: list[TableResolver] = []
98
+ for rel in self.relations:
99
+ child_resolvers.append(rel.resolver)
100
+
101
+ return MemDBResolver(
102
+ self,
103
+ records=[
104
+ {"name": "a", "id": 1},
105
+ {"name": "b", "id": 2},
106
+ {"name": "c", "id": 3},
107
+ ],
108
+ child_resolvers=child_resolvers,
109
+ )
110
+
111
+
112
+ class Table2(Table):
113
+ def __init__(self) -> None:
114
+ super().__init__(
115
+ name="table_2",
116
+ columns=[
117
+ schema.Column(
118
+ name="name",
119
+ type=pa.string(),
120
+ primary_key=True,
121
+ not_null=True,
122
+ unique=True,
123
+ ),
124
+ schema.Column(name="id", type=pa.int64()),
125
+ ],
126
+ title="Table 2",
127
+ description="Test Table 2",
128
+ )
129
+
130
+ @property
131
+ def resolver(self):
132
+ return MemDBResolver(
133
+ self,
134
+ records=[
135
+ {"name": "a", "id": 1},
136
+ {"name": "b", "id": 2},
137
+ {"name": "c", "id": 3},
138
+ ],
139
+ )
140
+
141
+
142
+ @dataclass
143
+ class Spec:
144
+ concurrency: int = field(default=1000)
145
+ queue_size: int = field(default=1000)
146
+
147
+
148
+ class MemDB(plugin.Plugin):
149
+ def __init__(self) -> None:
150
+ super().__init__(
151
+ NAME, VERSION, opts=plugin.plugin.Options(team="cloudquery", kind="source")
152
+ )
153
+ table1 = Table1()
154
+ table2 = Table2()
155
+ self._tables: Dict[str, schema.Table] = {
156
+ table1.name: table1,
157
+ table2.name: table2,
158
+ }
159
+ self._db: List[pa.RecordBatch] = []
160
+ self._client = Client()
161
+
162
+ def set_logger(self, logger) -> None:
163
+ self._logger = logger
164
+
165
+ def init(self, spec, no_connection: bool = False):
166
+ if no_connection:
167
+ return
168
+ self._spec_json = json.loads(spec)
169
+ self._spec = Spec(**self._spec_json)
170
+ self._scheduler = Scheduler(
171
+ concurrency=self._spec.concurrency,
172
+ queue_size=self._spec.queue_size,
173
+ logger=self._logger,
174
+ )
175
+
176
+ def get_tables(self, options: plugin.TableOptions = None) -> List[plugin.Table]:
177
+ tables = list(self._tables.values())
178
+
179
+ # set parent table relationships
180
+ for table in tables:
181
+ for relation in table.relations:
182
+ relation.parent = table
183
+
184
+ return schema.filter_dfs(tables, options.tables, options.skip_tables)
185
+
186
+ def sync(
187
+ self, options: plugin.SyncOptions
188
+ ) -> Generator[message.SyncMessage, None, None]:
189
+ resolvers: list[TableResolver] = []
190
+ for table in self.get_tables(
191
+ plugin.TableOptions(
192
+ tables=options.tables,
193
+ skip_tables=options.skip_tables,
194
+ skip_dependent_tables=options.skip_dependent_tables,
195
+ )
196
+ ):
197
+ resolvers.append(table.resolver)
198
+
199
+ return self._scheduler.sync(
200
+ self._client, resolvers, options.deterministic_cq_id
201
+ )
202
+
203
+ def write(self, writer: Generator[message.WriteMessage, None, None]) -> None:
204
+ for msg in writer:
205
+ if isinstance(msg, message.WriteMigrateTableMessage):
206
+ pass
207
+ elif isinstance(msg, message.WriteInsertMessage):
208
+ self._db.append(msg.record)
209
+ else:
210
+ raise NotImplementedError(f"Unknown message type {type(msg)}")
211
+
212
+ def read(self, table: Table) -> Generator[message.ReadMessage, None, None]:
213
+ for record in self._db:
214
+ recordMetadata = record.schema.metadata.get(METADATA_TABLE_NAME).decode(
215
+ "utf-8"
216
+ )
217
+ if recordMetadata == table.name:
218
+ yield message.ReadMessage(record)
219
+
220
+ def close(self) -> None:
221
+ self._db = {}
@@ -7,6 +7,7 @@ from cloudquery.plugin_v3 import plugin_pb2, plugin_pb2_grpc, arrow
7
7
  from cloudquery.sdk.message import (
8
8
  SyncInsertMessage,
9
9
  SyncMigrateTableMessage,
10
+ SyncErrorMessage,
10
11
  WriteInsertMessage,
11
12
  WriteMigrateTableMessage,
12
13
  WriteMessage,
@@ -77,6 +78,12 @@ class PluginServicer(plugin_pb2_grpc.PluginServicer):
77
78
  yield plugin_pb2.Sync.Response(
78
79
  migrate_table=plugin_pb2.Sync.MessageMigrateTable(table=buf)
79
80
  )
81
+ elif isinstance(msg, SyncErrorMessage) and request.withErrorMessages:
82
+ yield plugin_pb2.Sync.Response(
83
+ error=plugin_pb2.Sync.MessageError(
84
+ table_name=msg.table_name, error=msg.error
85
+ )
86
+ )
80
87
  else:
81
88
  # unknown sync message type
82
89
  raise NotImplementedError()
@@ -1,4 +1,9 @@
1
- from .sync import SyncMessage, SyncInsertMessage, SyncMigrateTableMessage
1
+ from .sync import (
2
+ SyncMessage,
3
+ SyncInsertMessage,
4
+ SyncMigrateTableMessage,
5
+ SyncErrorMessage,
6
+ )
2
7
  from .write import (
3
8
  WriteMessage,
4
9
  WriteInsertMessage,
@@ -13,3 +13,9 @@ class SyncInsertMessage(SyncMessage):
13
13
  class SyncMigrateTableMessage(SyncMessage):
14
14
  def __init__(self, table: pa.Schema):
15
15
  self.table = table
16
+
17
+
18
+ class SyncErrorMessage(SyncMessage):
19
+ def __init__(self, table_name: str, error: str):
20
+ self.table_name = table_name
21
+ self.error = error
@@ -8,6 +8,7 @@ from cloudquery.sdk.message import (
8
8
  SyncMessage,
9
9
  SyncInsertMessage,
10
10
  SyncMigrateTableMessage,
11
+ SyncErrorMessage,
11
12
  )
12
13
  from cloudquery.sdk.schema import Resource
13
14
  from cloudquery.sdk.stateclient.stateclient import StateClient
@@ -162,6 +163,7 @@ class Scheduler:
162
163
  depth=depth,
163
164
  exc_info=e,
164
165
  )
166
+ res.put(SyncErrorMessage(resolver.table.name, str(e)))
165
167
  finally:
166
168
  res.put(TableResolverFinished())
167
169
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudquery-plugin-sdk
3
- Version: 0.1.46
3
+ Version: 0.1.48
4
4
  Summary: CloudQuery Plugin SDK for Python
5
5
  Home-page: https://github.com/cloudquery/plugin-sdk-python
6
6
  Author: CloudQuery LTD
@@ -20,25 +20,25 @@ Classifier: Operating System :: OS Independent
20
20
  Classifier: Topic :: Internet
21
21
  Requires-Python: >=3.7
22
22
  License-File: LICENSE
23
- Requires-Dist: cloudquery-plugin-pb==0.0.46
23
+ Requires-Dist: cloudquery-plugin-pb==0.0.47
24
24
  Requires-Dist: exceptiongroup==1.3.0
25
- Requires-Dist: black==25.1.0
26
- Requires-Dist: grpcio==1.74.0
27
- Requires-Dist: grpcio-tools==1.74.0
25
+ Requires-Dist: black==25.9.0
26
+ Requires-Dist: grpcio==1.75.0
27
+ Requires-Dist: grpcio-tools==1.75.0
28
28
  Requires-Dist: iniconfig==2.1.0
29
29
  Requires-Dist: Jinja2==3.1.6
30
30
  Requires-Dist: MarkupSafe==3.0.2
31
- Requires-Dist: numpy==2.3.2
31
+ Requires-Dist: numpy==2.3.3
32
32
  Requires-Dist: packaging==24.2
33
33
  Requires-Dist: pandas==2.3.2
34
34
  Requires-Dist: pluggy==1.6.0
35
35
  Requires-Dist: protobuf>=6.31.1
36
36
  Requires-Dist: pyarrow==19.0.1
37
- Requires-Dist: pytest==8.4.1
37
+ Requires-Dist: pytest==8.4.2
38
38
  Requires-Dist: python-dateutil>=2.8.1
39
39
  Requires-Dist: pytz==2025.2
40
40
  Requires-Dist: six==1.17.0
41
- Requires-Dist: structlog==25.1.0
41
+ Requires-Dist: structlog==25.4.0
42
42
  Requires-Dist: tomli==2.2.1
43
43
  Requires-Dist: tzdata==2025.1
44
44
  Dynamic: author
@@ -1,21 +1,21 @@
1
- cloudquery-plugin-pb==0.0.46
1
+ cloudquery-plugin-pb==0.0.47
2
2
  exceptiongroup==1.3.0
3
- black==25.1.0
4
- grpcio==1.74.0
5
- grpcio-tools==1.74.0
3
+ black==25.9.0
4
+ grpcio==1.75.0
5
+ grpcio-tools==1.75.0
6
6
  iniconfig==2.1.0
7
7
  Jinja2==3.1.6
8
8
  MarkupSafe==3.0.2
9
- numpy==2.3.2
9
+ numpy==2.3.3
10
10
  packaging==24.2
11
11
  pandas==2.3.2
12
12
  pluggy==1.6.0
13
13
  protobuf>=6.31.1
14
14
  pyarrow==19.0.1
15
- pytest==8.4.1
15
+ pytest==8.4.2
16
16
  python-dateutil>=2.8.1
17
17
  pytz==2025.2
18
18
  six==1.17.0
19
- structlog==25.1.0
19
+ structlog==25.4.0
20
20
  tomli==2.2.1
21
21
  tzdata==2025.1
@@ -10,25 +10,25 @@ name = "cloudquery-plugin-sdk"
10
10
  description = "CloudQuery Plugin SDK for Python"
11
11
 
12
12
  dependencies = [
13
- "cloudquery-plugin-pb==0.0.46",
13
+ "cloudquery-plugin-pb==0.0.47",
14
14
  "exceptiongroup==1.3.0",
15
- "black==25.1.0",
16
- "grpcio==1.74.0",
17
- "grpcio-tools==1.74.0",
15
+ "black==25.9.0",
16
+ "grpcio==1.75.0",
17
+ "grpcio-tools==1.75.0",
18
18
  "iniconfig==2.1.0",
19
19
  "Jinja2==3.1.6",
20
20
  "MarkupSafe==3.0.2",
21
- "numpy==2.3.2",
21
+ "numpy==2.3.3",
22
22
  "packaging==24.2",
23
23
  "pandas==2.3.2",
24
24
  "pluggy==1.6.0",
25
25
  "protobuf>=6.31.1",
26
26
  "pyarrow==19.0.1",
27
- "pytest==8.4.1",
27
+ "pytest==8.4.2",
28
28
  "python-dateutil>=2.8.1",
29
29
  "pytz==2025.2",
30
30
  "six==1.17.0",
31
- "structlog==25.1.0",
31
+ "structlog==25.4.0",
32
32
  "tomli==2.2.1",
33
33
  "tzdata==2025.1",
34
34
  ]
@@ -51,7 +51,7 @@ packages = [
51
51
  ]
52
52
  setuptools.setup(
53
53
  name=name,
54
- version="0.1.46",
54
+ version="0.1.48",
55
55
  description=description,
56
56
  long_description=long_description,
57
57
  author="CloudQuery LTD",
@@ -1,118 +0,0 @@
1
- import json
2
-
3
- from cloudquery.sdk import plugin
4
- from cloudquery.sdk import message
5
- from cloudquery.sdk import schema
6
- from typing import List, Generator, Dict
7
- import pyarrow as pa
8
- from cloudquery.sdk.schema.table import Table
9
- from cloudquery.sdk.types import JSONType
10
- from dataclasses import dataclass, field
11
-
12
- NAME = "memdb"
13
- VERSION = "development"
14
-
15
-
16
- @dataclass
17
- class Spec:
18
- abc: str = field(default="abc")
19
-
20
-
21
- class MemDB(plugin.Plugin):
22
- def __init__(self) -> None:
23
- super().__init__(
24
- NAME, VERSION, opts=plugin.plugin.Options(team="cloudquery", kind="source")
25
- )
26
- self._db: Dict[str, pa.RecordBatch] = {}
27
- self._tables: Dict[str, schema.Table] = {
28
- "table_1": schema.Table(
29
- name="table_1",
30
- columns=[
31
- schema.Column(
32
- name="name",
33
- type=pa.string(),
34
- primary_key=True,
35
- not_null=True,
36
- unique=True,
37
- ),
38
- schema.Column(
39
- name="id",
40
- type=pa.string(),
41
- primary_key=True,
42
- not_null=True,
43
- unique=True,
44
- incremental_key=True,
45
- ),
46
- ],
47
- title="Table 1",
48
- description="Test Table 1",
49
- is_incremental=True,
50
- relations=[
51
- schema.Table(
52
- name="table_1_relation_1",
53
- columns=[
54
- schema.Column(
55
- name="name",
56
- type=pa.string(),
57
- primary_key=True,
58
- not_null=True,
59
- unique=True,
60
- ),
61
- schema.Column(name="data", type=JSONType()),
62
- ],
63
- title="Table 1 Relation 1",
64
- description="Test Table 1 Relation 1",
65
- )
66
- ],
67
- ),
68
- "table_2": schema.Table(
69
- name="table_2",
70
- columns=[
71
- schema.Column(
72
- name="name",
73
- type=pa.string(),
74
- primary_key=True,
75
- not_null=True,
76
- unique=True,
77
- ),
78
- schema.Column(name="id", type=pa.string()),
79
- ],
80
- title="Table 2",
81
- description="Test Table 2",
82
- ),
83
- }
84
-
85
- def init(self, spec, no_connection: bool = False):
86
- if no_connection:
87
- return
88
- self._spec_json = json.loads(spec)
89
- self._spec = Spec(**self._spec_json)
90
-
91
- def get_tables(self, options: plugin.TableOptions = None) -> List[plugin.Table]:
92
- tables = list(self._tables.values())
93
- return schema.filter_dfs(tables, options.tables, options.skip_tables)
94
-
95
- def sync(
96
- self, options: plugin.SyncOptions
97
- ) -> Generator[message.SyncMessage, None, None]:
98
- for table, record in self._db.items():
99
- yield message.SyncInsertMessage(record)
100
-
101
- def write(self, writer: Generator[message.WriteMessage, None, None]) -> None:
102
- for msg in writer:
103
- if isinstance(msg, message.WriteMigrateTableMessage):
104
- if msg.table.name not in self._db:
105
- self._db[msg.table.name] = msg.table
106
- self._tables[msg.table.name] = msg.table
107
- elif isinstance(msg, message.WriteInsertMessage):
108
- table = schema.Table.from_arrow_schema(msg.record.schema)
109
- self._db[table.name] = msg.record
110
- else:
111
- raise NotImplementedError(f"Unknown message type {type(msg)}")
112
-
113
- def read(self, table: Table) -> Generator[message.ReadMessage, None, None]:
114
- for table, record in self._db.items():
115
- yield message.ReadMessage(record)
116
-
117
- def close(self) -> None:
118
- self._db = {}