solax-py-library 1.0.0.22__py3-none-any.whl → 1.0.0.24__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.
@@ -1,7 +1,9 @@
1
- from .snap_shot import SnapshotCore
2
- from .parser import Parser
3
-
4
- __all__ = [
5
- "SnapshotCore",
6
- "Parser",
7
- ]
1
+ from .base_modbus import ModbusClientBase
2
+ from .snap_shot import SnapshotCore
3
+ from .parser import Parser
4
+
5
+ __all__ = [
6
+ "ModbusClientBase",
7
+ "SnapshotCore",
8
+ "Parser",
9
+ ]
@@ -1,225 +1,261 @@
1
- import re
2
- import struct
3
-
4
- from solax_py_library.snap_shot.types.address import CommandType
5
- from solax_py_library.snap_shot.constant.crc_table import CRC_Table
6
-
7
-
8
- class Parser:
9
- def parse(self, char16):
10
- """
11
- :return:
12
- """
13
- task_id = self.ascii_to_str(char16[12:76]) # task_id
14
- device_type = int(char16[76:78]) # 设备类型
15
- device_sn = self.ascii_to_str(char16[78:118]) # 设备SN
16
- business_type = int(char16[118:120])
17
- data = char16[120:]
18
- return {
19
- "task_id": task_id,
20
- "sn": device_sn,
21
- "device_type": device_type,
22
- "business_type": business_type,
23
- "message": char16,
24
- "data": data,
25
- }
26
-
27
- def ascii_to_str(self, data: str):
28
- """阿斯科码转字符串"""
29
- pattern = re.compile(".{2}")
30
- message = "\\u00" + "\\u00".join(pattern.findall(data))
31
- message = message.replace("\\u0000", "")
32
- message = bytes(message, encoding="utf-8").decode("unicode-escape")
33
- return message
34
-
35
- def upload_data(self, big_data: bytes, task_id: str, upload_data):
36
- business_type = 1 # 1 代表调试信息
37
- data_type = 0 # 0代表故障录波
38
-
39
- # 分片上传(每包1K
40
- chunk_size = 1024
41
- total_chunks = (len(big_data) + chunk_size - 1) // chunk_size
42
-
43
- # 遍历分片并构造数据包
44
- for chunk_idx, chunk_data in self.data_chunk_generator(big_data, chunk_size):
45
- frame = self.build_data_packet_frame(
46
- task_id=task_id,
47
- business_type=business_type,
48
- data_type=data_type,
49
- total_packets=total_chunks,
50
- current_packet=chunk_idx,
51
- chunk_data=chunk_data,
52
- )
53
-
54
- print(f"发送包 {chunk_idx + 1}/{total_chunks}, 长度={len(frame)} 字节")
55
- upload_data(frame)
56
-
57
- def data_chunk_generator(self, data: bytes, chunk_size: int = 1024):
58
- """
59
- 将大数据按固定包大小分片
60
- :param data: 原始数据字节流
61
- :param chunk_size: 每包最大字节数(默认1024)
62
- :yield: (当前包序号, 分片数据)
63
- """
64
- total = len(data)
65
- if total == 0:
66
- yield (0, b"") # 空数据单独处理
67
- return
68
-
69
- total_chunks = (total + chunk_size - 1) // chunk_size
70
-
71
- for i in range(total_chunks):
72
- start = i * chunk_size
73
- end = start + chunk_size
74
- yield (i, data[start:end])
75
-
76
- def build_response_frame(
77
- self, task_id: str, business_type: int, ack_code: int
78
- ) -> bytes:
79
- """
80
- 构建接收应答帧(指令类型 0x80
81
- :param task_id: 任务ID(32字节)
82
- :param business_type: 业务类型(0或1)
83
- :param ack_code: 0-成功,1-失败,2-执行中
84
- """
85
- # 固定字段
86
- header = bytes([0x24, 0x24])
87
- func_code = bytes([0x05, 0x07]) # 主功能码5 + 子功能码7
88
-
89
- # 数据域
90
- task_bytes = task_id.encode("ascii")[:32].ljust(32, b"\x00")
91
- business_byte = bytes([business_type])
92
- cmd_byte = bytes([CommandType.ACK.value])
93
- ack_byte = bytes([ack_code])
94
- data_part = task_bytes + business_byte + cmd_byte + ack_byte
95
-
96
- # 计算长度(功能码2字节 + 数据域37字节 + CRC2字节 = 41)
97
- frame_length = len(func_code) + len(data_part) + 2
98
- length_bytes = struct.pack("<H", frame_length)
99
-
100
- # 构建临时帧并计算CRC
101
- temp_frame = header + length_bytes + func_code + data_part
102
- crc = self.crc(temp_frame.hex()).upper()
103
- full_frame = temp_frame + bytes.fromhex(crc)
104
- return full_frame
105
-
106
- def build_total_packets_frame(
107
- self, task_id: str, business_type: int, data_type: int, total_packets: int
108
- ) -> bytes:
109
- """
110
- 构建上报总包数帧(指令类型 0x81)
111
- :param total_packets: 总包数(若为0,平台停止接收)
112
- """
113
- header = bytes([0x24, 0x24])
114
- func_code = bytes([0x05, 0x07])
115
-
116
- # 数据域
117
- task_bytes = task_id.encode("ascii")[:32].ljust(32, b"\x00")
118
- business_byte = bytes([business_type])
119
- cmd_byte = bytes([CommandType.TOTAL_PACKETS.value])
120
- data_length = struct.pack("<H", 2) # 数据长度固定2字节
121
- data_type_byte = bytes([data_type])
122
- total_packets_bytes = struct.pack("<H", total_packets)
123
-
124
- data_part = (
125
- task_bytes
126
- + business_byte
127
- + cmd_byte
128
- + data_length
129
- + data_type_byte
130
- + total_packets_bytes
131
- )
132
-
133
- # 计算长度
134
- frame_length = len(func_code) + len(data_part) + 2
135
- length_bytes = struct.pack("<H", frame_length)
136
-
137
- # 附加CRC
138
- temp_frame = header + length_bytes + func_code + data_part
139
- crc = self.crc(temp_frame.hex()).upper()
140
- return temp_frame + bytes.fromhex(crc)
141
-
142
- def build_data_packet_frame(
143
- self,
144
- task_id: str,
145
- business_type: int,
146
- data_type: int,
147
- total_packets: int,
148
- current_packet: int,
149
- chunk_data: bytes,
150
- ) -> bytes:
151
- """
152
- 构建具体分包数据帧(指令类型 0x82)
153
- """
154
- header = bytes([0x24, 0x24])
155
- func_code = bytes([0x05, 0x07])
156
-
157
- # 数据域
158
- task_bytes = task_id.encode("ascii")[:32].ljust(32, b"\x00")
159
- business_byte = bytes([business_type])
160
- cmd_byte = bytes([CommandType.DATA_PACKET.value])
161
- data_type_byte = bytes([data_type])
162
- total_packets_bytes = struct.pack("<H", total_packets)
163
- current_packet_bytes = struct.pack("<H", current_packet)
164
- data_length = struct.pack("<H", len(chunk_data))
165
-
166
- data_part = (
167
- task_bytes
168
- + business_byte
169
- + cmd_byte
170
- + data_type_byte
171
- + total_packets_bytes
172
- + current_packet_bytes
173
- + data_length
174
- + chunk_data
175
- )
176
-
177
- # 计算长度
178
- frame_length = len(func_code) + len(data_part) + 2
179
- length_bytes = struct.pack("<H", frame_length)
180
-
181
- # 附加CRC
182
- temp_frame = header + length_bytes + func_code + data_part
183
- crc = self.crc(temp_frame.hex()).upper()
184
- return temp_frame + bytes.fromhex(crc)
185
-
186
- def build_error_frame(
187
- self, task_id: str, business_type: int, error_type: int
188
- ) -> bytes:
189
- """
190
- 构建报错应答帧(指令类型 0x83)
191
-
192
- """
193
- header = bytes([0x24, 0x24])
194
- func_code = bytes([0x05, 0x07])
195
-
196
- # 数据域
197
- task_bytes = task_id.encode("ascii")[:32].ljust(32, b"\x00")
198
- business_byte = bytes([business_type])
199
- cmd_byte = bytes([CommandType.ERROR.value])
200
- error_byte = bytes([error_type])
201
- data_part = task_bytes + business_byte + cmd_byte + error_byte
202
-
203
- # 计算长度
204
- frame_length = len(func_code) + len(data_part) + 2
205
- length_bytes = struct.pack("<H", frame_length)
206
-
207
- # 附加CRC
208
- temp_frame = header + length_bytes + func_code + data_part
209
- crc = self.crc(temp_frame.hex()).upper()
210
- return temp_frame + bytes.fromhex(crc)
211
-
212
- def crc(self, message):
213
- """获取校验位, message: 除去校验位"""
214
- crc = 0
215
- i = 0
216
- length = len(message) // 2
217
- while length > 0:
218
- crc &= 0xFFFFFFFF
219
- da = crc // 256
220
- da &= 0xFF
221
- crc <<= 8
222
- crc ^= CRC_Table[da ^ int(message[i : i + 2], 16)]
223
- i += 2
224
- length -= 1
225
- return f"{crc & 0xffff:04x}"
1
+ import re
2
+ import struct
3
+
4
+ from solax_py_library.snap_shot.types.address import CommandType
5
+ from solax_py_library.snap_shot.constant.crc_table import CRC_Table
6
+
7
+
8
+ class Parser:
9
+ def parse(self, char16):
10
+ """
11
+ :return:
12
+ """
13
+ task_id = self.ascii_to_str(char16[12:76]) # task_id
14
+ device_type = int(char16[76:78]) # 设备类型
15
+ device_sn = self.ascii_to_str(char16[78:118]) # 设备SN
16
+ business_type = int(char16[118:120])
17
+ data = char16[120:]
18
+ return {
19
+ "task_id": task_id,
20
+ "sn": device_sn,
21
+ "device_type": device_type,
22
+ "business_type": business_type,
23
+ "message": char16,
24
+ "data": data,
25
+ }
26
+
27
+ def ascii_to_str(self, data: str):
28
+ """阿斯科码转字符串"""
29
+ pattern = re.compile(".{2}")
30
+ message = "\\u00" + "\\u00".join(pattern.findall(data))
31
+ message = message.replace("\\u0000", "")
32
+ message = bytes(message, encoding="utf-8").decode("unicode-escape")
33
+ return message
34
+
35
+ def upload_data(self, key: int, big_data: bytes, task_id: str, snap_upload_data):
36
+ business_type = 1 # 1 代表调试信息
37
+ data_type = 0 # 0代表故障录波
38
+
39
+ # 分片上传(每包10K
40
+ chunk_size = 10240
41
+ total_chunks = (len(big_data) + chunk_size - 1) // chunk_size
42
+
43
+ # 遍历分片并构造数据包
44
+ for chunk_idx, chunk_data in self.data_chunk_generator(big_data, chunk_size):
45
+ frame = self.build_data_packet_frame(
46
+ task_id=task_id,
47
+ business_type=business_type,
48
+ data_type=data_type,
49
+ total_packets=total_chunks,
50
+ current_packet=key,
51
+ chunk_data=chunk_data,
52
+ )
53
+ snap_upload_data(frame)
54
+
55
+ def data_chunk_generator(self, data: bytes, chunk_size: int = 1024):
56
+ """
57
+ 将大数据按固定包大小分片
58
+ :param data: 原始数据字节流
59
+ :param chunk_size: 每包最大字节数(默认1024)
60
+ :yield: (当前包序号, 分片数据)
61
+ """
62
+ total = len(data)
63
+ if total == 0:
64
+ yield (0, b"") # 空数据单独处理
65
+ return
66
+
67
+ total_chunks = (total + chunk_size - 1) // chunk_size
68
+
69
+ for i in range(total_chunks):
70
+ start = i * chunk_size
71
+ end = start + chunk_size
72
+ yield (i, data[start:end])
73
+
74
+ def build_response_frame(
75
+ self, task_id: str, business_type: int, ack_code: int
76
+ ) -> bytes:
77
+ """
78
+ 构建接收应答帧(指令类型 0x80)
79
+ :param task_id: 任务ID(32字节)
80
+ :param business_type: 业务类型(0或1
81
+ :param ack_code: 0-成功,1-失败,2-执行中
82
+ """
83
+ # 固定字段
84
+ header = bytes([0x24, 0x24])
85
+ func_code = bytes([0x05, 0x07]) # 主功能码5 + 子功能码7
86
+
87
+ # 数据域
88
+ task_bytes = task_id.encode("ascii")[:32].ljust(32, b"\x00")
89
+ business_byte = bytes([business_type])
90
+ cmd_byte = bytes([CommandType.ACK.value])
91
+ ack_byte = bytes([ack_code])
92
+ data_part = task_bytes + business_byte + cmd_byte + ack_byte
93
+
94
+ # 计算长度(功能码2字节 + 数据域37字节 + CRC2字节 = 41)
95
+ frame_length = len(func_code) + len(data_part) + 2
96
+ length_bytes = struct.pack("<H", frame_length)
97
+
98
+ # 构建临时帧并计算CRC
99
+ temp_frame = header + length_bytes + func_code + data_part
100
+ crc = self.crc(temp_frame.hex()).upper()
101
+ full_frame = temp_frame + bytes.fromhex(crc)
102
+ return full_frame
103
+
104
+ def build_response_all_pack_number(
105
+ self, task_id: str, business_type: int, total_packets: int
106
+ ) -> bytes:
107
+ """
108
+ 回复上传总报数
109
+ :param task_id: 任务ID(32字节)
110
+ :param business_type: 业务类型1
111
+ :param total_packets: 总书记包数
112
+ """
113
+ # 固定字段
114
+ header = bytes([0x24, 0x24])
115
+ func_code = bytes([0x05, 0x07]) # 主功能码5 + 子功能码7
116
+
117
+ # 数据域
118
+ task_bytes = task_id.encode("ascii")[:32].ljust(32, b"\x00")
119
+ business_byte = bytes([business_type])
120
+ cmd_byte = bytes([CommandType.TOTAL_PACKETS.value])
121
+ data_length = struct.pack("<H", 3)
122
+ data_type_byte = bytes([7]) # 和云平台约定故障录波就传7
123
+ total_packets_bytes = struct.pack("<H", total_packets)
124
+ data_part = (
125
+ task_bytes
126
+ + business_byte
127
+ + cmd_byte
128
+ + data_length
129
+ + data_type_byte
130
+ + total_packets_bytes
131
+ )
132
+
133
+ frame_length = len(func_code) + len(data_part) + 2
134
+ length_bytes = struct.pack("<H", frame_length)
135
+
136
+ # 构建临时帧并计算CRC
137
+ temp_frame = header + length_bytes + func_code + data_part
138
+ crc = self.crc(temp_frame.hex()).upper()
139
+ full_frame = temp_frame + bytes.fromhex(crc)
140
+ return full_frame
141
+
142
+ def build_total_packets_frame(
143
+ self, task_id: str, business_type: int, data_type: int, total_packets: int
144
+ ) -> bytes:
145
+ """
146
+ 构建上报总包数帧(指令类型 0x81)
147
+ :param total_packets: 总包数(若为0,平台停止接收)
148
+ """
149
+ header = bytes([0x24, 0x24])
150
+ func_code = bytes([0x05, 0x07])
151
+
152
+ # 数据域
153
+ task_bytes = task_id.encode("ascii")[:32].ljust(32, b"\x00")
154
+ business_byte = bytes([business_type])
155
+ cmd_byte = bytes([CommandType.TOTAL_PACKETS.value])
156
+ data_length = struct.pack("<H", 2) # 数据长度固定2字节
157
+ data_type_byte = bytes([data_type])
158
+ total_packets_bytes = struct.pack("<H", total_packets)
159
+
160
+ data_part = (
161
+ task_bytes
162
+ + business_byte
163
+ + cmd_byte
164
+ + data_length
165
+ + data_type_byte
166
+ + total_packets_bytes
167
+ )
168
+
169
+ # 计算长度
170
+ frame_length = len(func_code) + len(data_part) + 2
171
+ length_bytes = struct.pack("<H", frame_length)
172
+
173
+ # 附加CRC
174
+ temp_frame = header + length_bytes + func_code + data_part
175
+ crc = self.crc(temp_frame.hex()).upper()
176
+ return temp_frame + bytes.fromhex(crc)
177
+
178
+ def build_data_packet_frame(
179
+ self,
180
+ task_id: str,
181
+ business_type: int,
182
+ data_type: int,
183
+ total_packets: int,
184
+ current_packet: int,
185
+ chunk_data: bytes,
186
+ ) -> bytes:
187
+ """
188
+ 构建具体分包数据帧(指令类型 0x82)
189
+ """
190
+ header = bytes([0x24, 0x24])
191
+ func_code = bytes([0x05, 0x07])
192
+
193
+ # 数据域
194
+ task_bytes = task_id.encode("ascii")[:32].ljust(32, b"\x00")
195
+ business_byte = bytes([business_type])
196
+ cmd_byte = bytes([CommandType.DATA_PACKET.value])
197
+ data_type_byte = bytes([data_type])
198
+ total_packets_bytes = struct.pack("<H", total_packets)
199
+ current_packet_bytes = struct.pack("<H", current_packet)
200
+ data_length = struct.pack("<H", len(chunk_data))
201
+
202
+ data_part = (
203
+ task_bytes
204
+ + business_byte
205
+ + cmd_byte
206
+ + data_type_byte
207
+ + total_packets_bytes
208
+ + current_packet_bytes
209
+ + data_length
210
+ + chunk_data
211
+ )
212
+
213
+ # 计算长度
214
+ frame_length = len(func_code) + len(data_part) + 2
215
+ length_bytes = struct.pack("<H", frame_length)
216
+
217
+ # 附加CRC
218
+ temp_frame = header + length_bytes + func_code + data_part
219
+ crc = self.crc(temp_frame.hex()).upper()
220
+ return temp_frame + bytes.fromhex(crc)
221
+
222
+ def build_error_frame(
223
+ self, task_id: str, business_type: int, error_type: int
224
+ ) -> bytes:
225
+ """
226
+ 构建报错应答帧(指令类型 0x83)
227
+
228
+ """
229
+ header = bytes([0x24, 0x24])
230
+ func_code = bytes([0x05, 0x07])
231
+
232
+ # 数据域
233
+ task_bytes = task_id.encode("ascii")[:32].ljust(32, b"\x00")
234
+ business_byte = bytes([business_type])
235
+ cmd_byte = bytes([CommandType.ERROR.value])
236
+ error_byte = bytes([error_type])
237
+ data_part = task_bytes + business_byte + cmd_byte + error_byte
238
+
239
+ # 计算长度
240
+ frame_length = len(func_code) + len(data_part) + 2
241
+ length_bytes = struct.pack("<H", frame_length)
242
+
243
+ # 附加CRC
244
+ temp_frame = header + length_bytes + func_code + data_part
245
+ crc = self.crc(temp_frame.hex()).upper()
246
+ return temp_frame + bytes.fromhex(crc)
247
+
248
+ def crc(self, message):
249
+ """获取校验位, message: 除去校验位"""
250
+ crc = 0
251
+ i = 0
252
+ length = len(message) // 2
253
+ while length > 0:
254
+ crc &= 0xFFFFFFFF
255
+ da = crc // 256
256
+ da &= 0xFF
257
+ crc <<= 8
258
+ crc ^= CRC_Table[da ^ int(message[i : i + 2], 16)]
259
+ i += 2
260
+ length -= 1
261
+ return f"{crc & 0xffff:04x}"
@@ -6,6 +6,7 @@ from solax_py_library.snap_shot.exceptions import SnapshotTimeoutError
6
6
  from solax_py_library.snap_shot.core.base_modbus import ModbusClientBase
7
7
  from solax_py_library.snap_shot.types.address import *
8
8
  from solax_py_library.utils.common import retry
9
+ from .parser import Parser
9
10
 
10
11
 
11
12
  class SnapshotCore:
@@ -107,6 +108,11 @@ class SnapshotCore:
107
108
  packindex = 0
108
109
 
109
110
  await self._set_snap_shot_data_index(index) # 设置快照索引
111
+ # 把每次录波参数数量 和参数数据点数量假如的头部
112
+ param_number = await self.modbus.read_registers(
113
+ SnapshotRegisterAddress.SNAPSHOT_REGISTERADDRESS_CHANNELNUMBER.value, 2
114
+ )
115
+ self.all_snap_shot_data.setdefault(index, []).extend(param_number)
110
116
  while readdatanum < DataNumber:
111
117
  if await self._get_data_pack_read_state() is False: # 获取数据包读取状态
112
118
  raise self.snap_except("读取数据包错误")
@@ -114,7 +120,7 @@ class SnapshotCore:
114
120
  siglepackdatanum = DataNumber - readdatanum
115
121
  if siglepackdatanum > 256:
116
122
  siglepackdatanum = 256
117
- print(f"第{index}次快照,第{packindex}包,读取数据个数:{siglepackdatanum}")
123
+ # print(f"第{index}次快照,第{packindex}包,读取数据个数:{siglepackdatanum}")
118
124
 
119
125
  await self._get_data_pack_index() # 取得数据包索引
120
126
  once_data = await self._get_data_pack(
@@ -143,6 +149,7 @@ class SnapshotCore:
143
149
  # print(f'取得数据包就绪状态')
144
150
  readcnt = 0
145
151
  result = False
152
+ # print(f"readcnt:{readcnt}")
146
153
  while readcnt < 100:
147
154
  result = await self.modbus.read_registers(
148
155
  SnapshotRegisterAddress.SNAPSHOT_REGISTERADDRESS_PACKDATASTATUS.value, 1
@@ -186,7 +193,7 @@ class SnapshotCore:
186
193
  response = await self.get_data_pack_h_address(register_num // 2)
187
194
  DataPack.extend(response)
188
195
 
189
- # print(f'获取快照数据包返回值:{DataPack}')
196
+ print(f"获取快照数据包返回值:{DataPack}")
190
197
  return DataPack
191
198
 
192
199
  @retry(max_attempts=3, delay=0.5, assign_exception=SnapshotTimeoutError)
@@ -218,11 +225,18 @@ class SnapshotCore:
218
225
  # print(f'清除数据包就绪状态返回值:{response}')
219
226
 
220
227
  @classmethod
221
- async def start(cls, modbus_client, snap_shot_index: int = 0, snap_exception=None):
228
+ async def start(
229
+ cls,
230
+ modbus_client,
231
+ snap_shot_index: int = 0,
232
+ snap_exception=None,
233
+ snap_upload_data=None,
234
+ task_id="",
235
+ ):
222
236
  """启动故障录波
223
237
  snap_shot_index : 代表第几个故障 如果传0 就默认读取所有故障
224
238
  """
225
- # print'start.................................')
239
+ print("start.................................")
226
240
  instance = cls(modbus_client, snap_exception)
227
241
  try:
228
242
  # 第一步 设置快照芯片源
@@ -231,6 +245,10 @@ class SnapshotCore:
231
245
  await instance._set_export_device()
232
246
  # 第三步 获取设备总数
233
247
  total_number = await instance._get_snapshot_total_number()
248
+ total_number_message = Parser().build_response_all_pack_number(
249
+ task_id, 1, total_number
250
+ )
251
+ snap_upload_data(total_number_message)
234
252
  if total_number < 1:
235
253
  return instance.snap_except("无效的故障录波总数")
236
254
  # 第四步 开始录波
@@ -238,9 +256,9 @@ class SnapshotCore:
238
256
  # 第5步 获取快照数据参数
239
257
  total_data_length = await instance._get_snapshot_dataPara()
240
258
  # 第六步 读数据
241
- # for index in range(1, total_number + 1):
242
- # await instance._get_Single_snap_shot_data(index, total_data_length)
243
- await instance._get_Single_snap_shot_data(1, total_data_length)
259
+ for index in range(1, total_number + 1):
260
+ await instance._get_Single_snap_shot_data(index, total_data_length)
261
+ # await instance._get_Single_snap_shot_data(1, total_data_length)
244
262
 
245
263
  return instance.all_snap_data
246
264
 
@@ -1,3 +1,3 @@
1
- from .service import upload, upload_service
2
-
3
- __all__ = ["upload", "upload_service"]
1
+ from .service import upload, upload_service
2
+
3
+ __all__ = ["upload", "upload_service"]
@@ -1,3 +1,3 @@
1
- from . import upload_service, data_adapter
2
-
3
- __all__ = ["upload_service", "data_adapter"]
1
+ from . import upload_service, data_adapter
2
+
3
+ __all__ = ["upload_service", "data_adapter"]
@@ -1,5 +1,5 @@
1
- from .base import BaseDataAdapter
2
- from .csv import CSVDataAdapter
3
-
4
-
5
- __all__ = ["BaseDataAdapter", "CSVDataAdapter"]
1
+ from .base import BaseDataAdapter
2
+ from .csv import CSVDataAdapter
3
+
4
+
5
+ __all__ = ["BaseDataAdapter", "CSVDataAdapter"]
@@ -1,9 +1,9 @@
1
- from abc import ABCMeta, abstractmethod
2
-
3
-
4
- class BaseDataAdapter(metaclass=ABCMeta):
5
- data_type = None
6
-
7
- @abstractmethod
8
- def parse_data(self, data):
9
- ...
1
+ from abc import ABCMeta, abstractmethod
2
+
3
+
4
+ class BaseDataAdapter(metaclass=ABCMeta):
5
+ data_type = None
6
+
7
+ @abstractmethod
8
+ def parse_data(self, data):
9
+ ...