protobin 0.0.2__tar.gz → 0.0.4__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.
@@ -0,0 +1,119 @@
1
+ Metadata-Version: 2.3
2
+ Name: protobin
3
+ Version: 0.0.4
4
+ Summary: Python library for encode and decode data in protobin format
5
+ Project-URL: Homepage, https://github.com/drmelectronic/protobin-python
6
+ Project-URL: Bug Tracker, https://github.com/drmelectronic/protobin-python/issues
7
+ Author-email: Daniel Robles <drm.electronic@gmail.com>
8
+ License: MIT License
9
+
10
+ Copyright (c) [Año] [Tu Nombre]
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE. 1
29
+ 1. en.wikipedia.org
30
+ en.wikipedia.org
31
+ License-File: LICENSE.txt
32
+ Classifier: License :: OSI Approved :: MIT License
33
+ Classifier: Operating System :: OS Independent
34
+ Classifier: Programming Language :: Python :: 3
35
+ Requires-Python: >=3.9
36
+ Description-Content-Type: text/markdown
37
+
38
+ # protobin
39
+
40
+ **protobin** es una biblioteca Python diseñada para facilitar la interacción con el formato de transferencia de datos Protobin en modo binario. Esta biblioteca proporciona una interfaz sencilla y eficiente para:
41
+
42
+ * **Serializar** objetos Python en datos Protobin.
43
+ * **Deserializar** datos Protobin en objetos Python.
44
+ * **Validar** la integridad de los datos Protobin.
45
+
46
+ ## Instalación
47
+
48
+ Para instalar `protobin`, puedes utilizar pip:
49
+
50
+ ```bash
51
+ pip install protobin
52
+ ```
53
+
54
+ ## Cómo empezar
55
+
56
+ ### Primeros Pasos
57
+ Declare un protocolo de la siguiente forma:
58
+
59
+ ```python
60
+ from protobin import Protocol
61
+ protocol = Protocol(js={'medida': [
62
+ {'key': 'id', 'bytes': 1, 'type': 'unsigned'},
63
+ {'key': 'nombre', 'type': 'string'},
64
+ {'key': 'valor', 'bytes': 2, 'type': 'signed'}
65
+ ]})
66
+ ```
67
+
68
+ luego cree la variable que desea transmitir como un diccionario de python, codiféquela, decodifíquela, y compruebe que la información se recuperó correctamente
69
+
70
+ ```python
71
+ data = {'id': 2, 'nombre': 'Voltaje', 'valor': -20}
72
+ binary = protocol.encode(data, 'medida')
73
+ print('binary', binary)
74
+ recv = protocol.decode(binary, 'medida')
75
+ print('recv', recv)
76
+ ```
77
+
78
+ ### Archivo Json
79
+
80
+ El protocolo se declara en un archivo *.json o un objeto dict en python.
81
+ Éste contiene un diccionario donde cada clave del diccionario es el identificador de un formato.
82
+
83
+ ```json
84
+ {
85
+ "formato1": [{}, {}, {}],
86
+ "formato2": [{}, {}]
87
+ }
88
+ ```
89
+
90
+ Cada formato se declara como una lista de campos, y cada campo es representado por un diccionario, que debe tener un **key** para identificar el dato que se almacenará en esa posición, también debe tener un **type** que define el tipo de dato que se guardará y opcionalmente **bytes** o **length** para definir la cantidad de espacio o datos que se guardarán.
91
+
92
+
93
+ ### Tipos de Datos
94
+
95
+ **array** : Sirve para declarar listas de objetos, requiere el campo **array* que contiene un formato completo.
96
+
97
+ **bits** : Sirve para declarar una lista de valores booleanos como un arreglo de bits en la cantidad necesaria de bytes. Es opcional el campo **length** si se quiere fijar una cantidad de elementos y usar un byte menos en su codificación.
98
+
99
+ **bool** : Sirve para declarar un único valor booleano en un byte. No requiere campos adicionales, ocupa 1 byte.
100
+
101
+ **char** : Sirve para declarar un único valor booleano en un byte. No requiere campos adicionales, ocupa 1 byte.
102
+
103
+ **date** : Sirve para declarar un valor datetime.date. No requiere campos adicionales, ocupa 3 bytes.
104
+
105
+ **datetime** : Sirve para declarar un valor datetime.datetime con presicion de segundos. No requiere campos adicionales, ocupa 6 bytes.
106
+
107
+ **flags** : Sirve para declarar una lista de keys cuyos valores sean booleanos y representarlos en un arreglo de bits. No requiere campos adicionales.
108
+
109
+ **float** : Sirve para declarar un valor numérico con una precisión fija de decimales. Requiere el campo **bytes** y **decimales**, tamaño variable.
110
+
111
+ **signed** : Sirve para declarar un valor entero positivo. Requiere el campo **bytes**, tamaño variable.
112
+
113
+ **string** : Sirve para declarar un texto. Es opcional el campo **bytes**, tamaño variable.
114
+
115
+ **time** : Sirve para declarar un valor datetime.time con presicion de minutos. No requiere campos adicionales, ocupa 2 bytes.
116
+
117
+ **timestamp** : Sirve para declarar un valor datetime.datetime con presicion de microsegundos. No requiere campos adicionales, ocupa 8 bytes.
118
+
119
+ **unsigned** : Sirve para declarar un valor entero. Requiere el campo **bytes**, tamaño variable.
@@ -0,0 +1,82 @@
1
+ # protobin
2
+
3
+ **protobin** es una biblioteca Python diseñada para facilitar la interacción con el formato de transferencia de datos Protobin en modo binario. Esta biblioteca proporciona una interfaz sencilla y eficiente para:
4
+
5
+ * **Serializar** objetos Python en datos Protobin.
6
+ * **Deserializar** datos Protobin en objetos Python.
7
+ * **Validar** la integridad de los datos Protobin.
8
+
9
+ ## Instalación
10
+
11
+ Para instalar `protobin`, puedes utilizar pip:
12
+
13
+ ```bash
14
+ pip install protobin
15
+ ```
16
+
17
+ ## Cómo empezar
18
+
19
+ ### Primeros Pasos
20
+ Declare un protocolo de la siguiente forma:
21
+
22
+ ```python
23
+ from protobin import Protocol
24
+ protocol = Protocol(js={'medida': [
25
+ {'key': 'id', 'bytes': 1, 'type': 'unsigned'},
26
+ {'key': 'nombre', 'type': 'string'},
27
+ {'key': 'valor', 'bytes': 2, 'type': 'signed'}
28
+ ]})
29
+ ```
30
+
31
+ luego cree la variable que desea transmitir como un diccionario de python, codiféquela, decodifíquela, y compruebe que la información se recuperó correctamente
32
+
33
+ ```python
34
+ data = {'id': 2, 'nombre': 'Voltaje', 'valor': -20}
35
+ binary = protocol.encode(data, 'medida')
36
+ print('binary', binary)
37
+ recv = protocol.decode(binary, 'medida')
38
+ print('recv', recv)
39
+ ```
40
+
41
+ ### Archivo Json
42
+
43
+ El protocolo se declara en un archivo *.json o un objeto dict en python.
44
+ Éste contiene un diccionario donde cada clave del diccionario es el identificador de un formato.
45
+
46
+ ```json
47
+ {
48
+ "formato1": [{}, {}, {}],
49
+ "formato2": [{}, {}]
50
+ }
51
+ ```
52
+
53
+ Cada formato se declara como una lista de campos, y cada campo es representado por un diccionario, que debe tener un **key** para identificar el dato que se almacenará en esa posición, también debe tener un **type** que define el tipo de dato que se guardará y opcionalmente **bytes** o **length** para definir la cantidad de espacio o datos que se guardarán.
54
+
55
+
56
+ ### Tipos de Datos
57
+
58
+ **array** : Sirve para declarar listas de objetos, requiere el campo **array* que contiene un formato completo.
59
+
60
+ **bits** : Sirve para declarar una lista de valores booleanos como un arreglo de bits en la cantidad necesaria de bytes. Es opcional el campo **length** si se quiere fijar una cantidad de elementos y usar un byte menos en su codificación.
61
+
62
+ **bool** : Sirve para declarar un único valor booleano en un byte. No requiere campos adicionales, ocupa 1 byte.
63
+
64
+ **char** : Sirve para declarar un único valor booleano en un byte. No requiere campos adicionales, ocupa 1 byte.
65
+
66
+ **date** : Sirve para declarar un valor datetime.date. No requiere campos adicionales, ocupa 3 bytes.
67
+
68
+ **datetime** : Sirve para declarar un valor datetime.datetime con presicion de segundos. No requiere campos adicionales, ocupa 6 bytes.
69
+
70
+ **flags** : Sirve para declarar una lista de keys cuyos valores sean booleanos y representarlos en un arreglo de bits. No requiere campos adicionales.
71
+
72
+ **float** : Sirve para declarar un valor numérico con una precisión fija de decimales. Requiere el campo **bytes** y **decimales**, tamaño variable.
73
+
74
+ **signed** : Sirve para declarar un valor entero positivo. Requiere el campo **bytes**, tamaño variable.
75
+
76
+ **string** : Sirve para declarar un texto. Es opcional el campo **bytes**, tamaño variable.
77
+
78
+ **time** : Sirve para declarar un valor datetime.time con presicion de minutos. No requiere campos adicionales, ocupa 2 bytes.
79
+
80
+ **timestamp** : Sirve para declarar un valor datetime.datetime con presicion de microsegundos. No requiere campos adicionales, ocupa 8 bytes.
81
+
82
+ **unsigned** : Sirve para declarar un valor entero. Requiere el campo **bytes**, tamaño variable.
@@ -75,8 +75,7 @@ class FieldBase:
75
75
  def split(self, binary):
76
76
  if self.bytes:
77
77
  return binary[:self.bytes], binary[self.bytes:]
78
- self.bytes = binary[0]
79
- return binary[1:self.bytes + 1], binary[self.bytes + 1:]
78
+ return binary[1:binary[0] + 1], binary[binary[0] + 1:]
80
79
 
81
80
  def to_dict(self):
82
81
  return {
@@ -134,11 +133,18 @@ class FieldBits(FieldBase):
134
133
  self.length = js.get('length', 0)
135
134
  self.bytes = math.ceil(self.length / 8)
136
135
 
136
+ def decode(self, binary):
137
+ self.ensure_length(binary)
138
+ a, b, length = self.split(binary)
139
+ val = self.from_binary_bits(a, length)
140
+ return val, b
141
+
137
142
  def split(self, binary):
138
- if not self.length:
139
- self.length = binary[0]
140
- self.bytes = math.ceil(self.length / 8)
141
- return binary[1:self.bytes + 1], binary[self.bytes + 1:]
143
+ if self.length:
144
+ return binary[:self.bytes], binary[self.bytes:], self.length
145
+ length = binary[0]
146
+ bts = math.ceil(length / 8)
147
+ return binary[1:bts + 1], binary[bts + 1:], length
142
148
 
143
149
  def to_binary(self, val: List[bool]):
144
150
  if len(val) == 0:
@@ -150,18 +156,19 @@ class FieldBits(FieldBase):
150
156
  bits = ''
151
157
  for b in val:
152
158
  bits += '1' if b else '0'
153
- length = int(len(bits) / 8)
154
- binary += len(val).to_bytes(1, 'big', signed=False)
155
- binary += int(bits, 2).to_bytes(length, 'big', signed=False)
159
+ bts = int(len(bits) / 8)
160
+ if not self.length:
161
+ binary += len(val).to_bytes(1, 'big', signed=False)
162
+ binary += int(bits, 2).to_bytes(bts, 'big', signed=False)
156
163
  return binary
157
164
 
158
- def from_binary(self, binary):
165
+ def from_binary_bits(self, binary, length):
159
166
  numero = int.from_bytes(binary, 'big', signed=False)
160
167
  bits = bin(numero)[2:]
161
168
  val = [False] * 8
162
169
  for b in bits:
163
170
  val.append(b == '1')
164
- val = val[-self.length:]
171
+ val = val[-length:]
165
172
  return val
166
173
 
167
174
 
@@ -306,15 +313,14 @@ class FieldSigned(FieldBase):
306
313
  class FieldString(FieldBase):
307
314
 
308
315
  def to_binary(self, val):
309
- if self.bytes == 0:
310
- utf = str(val).encode('utf')[:255]
311
- return len(utf).to_bytes(1, 'big') + utf
316
+ if self.bytes:
317
+ utf = str(val).encode('utf')[:self.bytes]
318
+ return utf
319
+ utf = str(val).encode('utf')[:255]
320
+ return len(utf).to_bytes(1, 'big') + utf
312
321
 
313
322
  def from_binary(self, binary):
314
- if self.bytes == 0:
315
- self.bytes = int.from_bytes(binary[:1], 'big', signed=False)
316
- binary = binary[1:]
317
- return binary[:self.bytes].decode('utf')
323
+ return binary.decode('utf')
318
324
 
319
325
 
320
326
  class FieldTime(FieldBase):
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "protobin"
7
- version = "0.0.2"
7
+ version = "0.0.4"
8
8
  authors = [
9
9
  { name="Daniel Robles", email="drm.electronic@gmail.com" },
10
10
  ]
@@ -116,6 +116,7 @@ class BasicTest(unittest.TestCase):
116
116
  {'key': 'test', 'bytes': 0, 'type': 'string'}
117
117
  ]}],
118
118
  'bits': [{'key': 'test', 'type': 'bits'}],
119
+ 'bits_fixed': [{'key': 'test', 'type': 'bits', 'length': 7}],
119
120
  'bool': [{'key': 'test', 'bytes': 1, 'type': 'bool'}],
120
121
  'char': [{'key': 'test', 'bytes': 1, 'type': 'char'}],
121
122
  'date': [{'key': 'test', 'bytes': 1, 'type': 'date'}],
@@ -148,6 +149,15 @@ class BasicTest(unittest.TestCase):
148
149
  print('recv', recv)
149
150
  self.assertEqual(data, recv)
150
151
 
152
+ def test_bits_fixed(self):
153
+ data = {'test': [True, False, True, False, False, True, True]}
154
+ print('data', data)
155
+ binary = self.protocol.encode(data, 'bits_fixed')
156
+ print('binary', binary)
157
+ recv = self.protocol.decode(binary, 'bits_fixed')
158
+ print('recv', recv)
159
+ self.assertEqual(data, recv)
160
+
151
161
  def test_bool(self):
152
162
  data = {'test': False}
153
163
  binary = self.protocol.encode(data, 'bool')
@@ -207,6 +217,10 @@ class BasicTest(unittest.TestCase):
207
217
  binary = self.protocol.encode(data, 'string')
208
218
  recv = self.protocol.decode(binary, 'string')
209
219
  self.assertEqual(data, recv)
220
+ data = {'test': 'otro texto de prueba más largo'}
221
+ binary = self.protocol.encode(data, 'string')
222
+ recv = self.protocol.decode(binary, 'string')
223
+ self.assertEqual(data, recv)
210
224
 
211
225
  def test_timestamp(self):
212
226
  data = {'test': datetime.datetime(2024, 9, 13, 15, 23, 51, 265981)}
@@ -217,12 +231,23 @@ class BasicTest(unittest.TestCase):
217
231
 
218
232
  class AdvancedTest(unittest.TestCase):
219
233
 
220
- def setUp(self):
221
- self.parser = Protocol(file='demo.json')
222
-
223
- def test_report(self):
224
- binary = self.parser.encode(DATA, 'report')
225
- recv = self.parser.decode(binary, 'report')
234
+ def test_file(self):
235
+ protocol = Protocol(file='demo.json')
236
+ binary = protocol.encode(DATA, 'report')
237
+ recv = protocol.decode(binary, 'report')
226
238
  self.assertEqual(DATA, recv)
227
239
 
240
+ def test_json(self):
241
+ protocol = Protocol(js={'medida': [
242
+ {'key': 'id', 'bytes': 1, 'type': 'unsigned'},
243
+ {'key': 'nombre', 'type': 'string'},
244
+ {'key': 'valor', 'bytes': 2, 'type': 'signed'}
245
+ ]})
246
+ data = {'id': 2, 'nombre': 'Voltaje', 'valor': -20}
247
+ binary = protocol.encode(data, 'medida')
248
+ print('binary', binary)
249
+ recv = protocol.decode(binary, 'medida')
250
+ print('recv', recv)
251
+ self.assertEqual(data, recv)
252
+
228
253
 
protobin-0.0.2/PKG-INFO DELETED
@@ -1,51 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: protobin
3
- Version: 0.0.2
4
- Summary: Python library for encode and decode data in protobin format
5
- Project-URL: Homepage, https://github.com/drmelectronic/protobin-python
6
- Project-URL: Bug Tracker, https://github.com/drmelectronic/protobin-python/issues
7
- Author-email: Daniel Robles <drm.electronic@gmail.com>
8
- License: MIT License
9
-
10
- Copyright (c) [Año] [Tu Nombre]
11
-
12
- Permission is hereby granted, free of charge, to any person obtaining a copy
13
- of this software and associated documentation files (the "Software"), to deal
14
- in the Software without restriction, including without limitation the rights
15
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
- copies of the Software, and to permit persons to whom the Software is
17
- furnished to do so, subject to the following conditions:
18
-
19
- The above copyright notice and this permission notice shall be included in all
20
- copies or substantial portions of the Software.
21
-
22
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
- SOFTWARE. 1
29
- 1. en.wikipedia.org
30
- en.wikipedia.org
31
- License-File: LICENSE.txt
32
- Classifier: License :: OSI Approved :: MIT License
33
- Classifier: Operating System :: OS Independent
34
- Classifier: Programming Language :: Python :: 3
35
- Requires-Python: >=3.9
36
- Description-Content-Type: text/markdown
37
-
38
- # protobin
39
-
40
- **protobin** es una biblioteca Python diseñada para facilitar la interacción con el formato de transferencia de datos Protobin en modo binario. Esta biblioteca proporciona una interfaz sencilla y eficiente para:
41
-
42
- * **Serializar** objetos Python en datos Protobin.
43
- * **Deserializar** datos Protobin en objetos Python.
44
- * **Validar** la integridad de los datos Protobin.
45
-
46
- ## Instalación
47
-
48
- Para instalar `protobin-python`, puedes utilizar pip:
49
-
50
- ```bash
51
- pip install protobin
protobin-0.0.2/README.md DELETED
@@ -1,14 +0,0 @@
1
- # protobin
2
-
3
- **protobin** es una biblioteca Python diseñada para facilitar la interacción con el formato de transferencia de datos Protobin en modo binario. Esta biblioteca proporciona una interfaz sencilla y eficiente para:
4
-
5
- * **Serializar** objetos Python en datos Protobin.
6
- * **Deserializar** datos Protobin en objetos Python.
7
- * **Validar** la integridad de los datos Protobin.
8
-
9
- ## Instalación
10
-
11
- Para instalar `protobin-python`, puedes utilizar pip:
12
-
13
- ```bash
14
- pip install protobin
@@ -1,2 +0,0 @@
1
- import datetime
2
-
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes