pyRegRep 12__tar.gz → 14__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.
@@ -1,15 +1,25 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyRegRep
3
- Version: 12
4
- Summary: Your package description
5
- Author: Andrey Shapovalov
6
- Author-email: mt.andrey@gmail.com
3
+ Version: 14
4
+ Summary: Бібліотека для роботи з реєстрами та репозитаріями в Україні
5
+ Author-email: Andrii Shapovalov <mt.andrey@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/AndreyShapovalovVN/pyRegRep
8
+ Project-URL: Repository, https://github.com/AndreyShapovalovVN/pyRegRep.git
9
+ Project-URL: Issues, https://github.com/AndreyShapovalovVN/pyRegRep/issues
10
+ Keywords: registry,repositories,ukraine
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
7
18
  Requires-Python: >=3.10
8
19
  Description-Content-Type: text/markdown
9
20
  License-File: LICENSE
10
21
  Requires-Dist: lxml>=5.2.1
11
22
  Requires-Dist: xmltodict>=0.13.0
12
- Dynamic: author-email
13
23
  Dynamic: license-file
14
24
 
15
25
  # pyRegRep
@@ -28,6 +38,7 @@ Dynamic: license-file
28
38
  - ✅ Обробка всіх типів значень: Boolean, String, Integer, DateTime, Collection, InternationalString, AnyValue
29
39
  - ✅ Серіалізація даних у зручний Python-формат (`dict`)
30
40
  - ✅ Фабрика слотів `get_slot()` — програмне створення RIM-слотів за типом
41
+ - ✅ Builder-класи для елементів `RegistryObject`, `RepositoryItemRef`, `QueryResponse`, `Classification`
31
42
  - ✅ Серіалізація `AnyValueType` через `xmltodict` (параметр `any_type=True`)
32
43
  - ✅ Підтримка вкладених колекцій та складних структур
33
44
  - ✅ Безпечний доступ до вкладених даних через `deep_get()`
@@ -198,6 +209,38 @@ except ValueError as e:
198
209
 
199
210
  ---
200
211
 
212
+ ### Builder-класи XML елементів (`pyRegRep4.RIMElement`)
213
+
214
+ Публічні класи для побудови типових елементів RIM/query:
215
+
216
+ - `RegistryObject`
217
+ - `RepositoryItemRef`
218
+ - `QueryResponse`
219
+ - `Classification`
220
+
221
+ Усі класи мають однаковий базовий контракт:
222
+ - `element` — повертає `etree._Element` (або `ValueError`, якщо елемент ще не створено)
223
+ - `text` — серіалізований XML (`bytes`)
224
+ - `create_element(...)` — будує XML елемент і повертає `self` (chain-style)
225
+
226
+ ```python
227
+ from pyRegRep4.RIMElement import RepositoryItemRef, QueryResponse
228
+
229
+ ref = RepositoryItemRef().create_element(
230
+ "https://example.org/document.xml",
231
+ "Document",
232
+ )
233
+ print(ref.text)
234
+
235
+ response = QueryResponse().create_element(
236
+ "urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success",
237
+ "req-1",
238
+ )
239
+ print(response.element.tag)
240
+ ```
241
+
242
+ ---
243
+
201
244
  ### Функція `deep_get()` (`pyRegRep4.utils`)
202
245
 
203
246
  ```python
@@ -250,7 +293,7 @@ print(procedure) # [{"lang": "en", "value": "GetBirthCertificate"}]
250
293
  ```
251
294
  pyRegRep/
252
295
  ├── pyRegRep4/
253
- │ ├── __init__.py # Експорт: get_slot та типи слотів
296
+ │ ├── __init__.py # Експорт: get_slot, deep_get, Parsing, serialize_any_value_type
254
297
  │ ├── RIMElement.py # Класи слотів + фабрика get_slot()
255
298
  │ ├── RIMParsing.py # Парсер Parsing + serialize()
256
299
  │ ├── utils.py # deep_get() для вкладених словників
@@ -337,4 +380,4 @@ MIT License — див. файл [LICENSE](LICENSE)
337
380
 
338
381
  ---
339
382
 
340
- **Версія:** 12 · **Оновлено:** 2026-04-12
383
+ **Версія:** 13 · **Оновлено:** 2026-04-14
@@ -1,17 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: pyRegRep
3
- Version: 12
4
- Summary: Your package description
5
- Author: Andrey Shapovalov
6
- Author-email: mt.andrey@gmail.com
7
- Requires-Python: >=3.10
8
- Description-Content-Type: text/markdown
9
- License-File: LICENSE
10
- Requires-Dist: lxml>=5.2.1
11
- Requires-Dist: xmltodict>=0.13.0
12
- Dynamic: author-email
13
- Dynamic: license-file
14
-
15
1
  # pyRegRep
16
2
 
17
3
  Бібліотека Python для парсування та обробки XML документів у форматі RIM (Registry Information Model) / ebXML.
@@ -28,6 +14,7 @@ Dynamic: license-file
28
14
  - ✅ Обробка всіх типів значень: Boolean, String, Integer, DateTime, Collection, InternationalString, AnyValue
29
15
  - ✅ Серіалізація даних у зручний Python-формат (`dict`)
30
16
  - ✅ Фабрика слотів `get_slot()` — програмне створення RIM-слотів за типом
17
+ - ✅ Builder-класи для елементів `RegistryObject`, `RepositoryItemRef`, `QueryResponse`, `Classification`
31
18
  - ✅ Серіалізація `AnyValueType` через `xmltodict` (параметр `any_type=True`)
32
19
  - ✅ Підтримка вкладених колекцій та складних структур
33
20
  - ✅ Безпечний доступ до вкладених даних через `deep_get()`
@@ -198,6 +185,38 @@ except ValueError as e:
198
185
 
199
186
  ---
200
187
 
188
+ ### Builder-класи XML елементів (`pyRegRep4.RIMElement`)
189
+
190
+ Публічні класи для побудови типових елементів RIM/query:
191
+
192
+ - `RegistryObject`
193
+ - `RepositoryItemRef`
194
+ - `QueryResponse`
195
+ - `Classification`
196
+
197
+ Усі класи мають однаковий базовий контракт:
198
+ - `element` — повертає `etree._Element` (або `ValueError`, якщо елемент ще не створено)
199
+ - `text` — серіалізований XML (`bytes`)
200
+ - `create_element(...)` — будує XML елемент і повертає `self` (chain-style)
201
+
202
+ ```python
203
+ from pyRegRep4.RIMElement import RepositoryItemRef, QueryResponse
204
+
205
+ ref = RepositoryItemRef().create_element(
206
+ "https://example.org/document.xml",
207
+ "Document",
208
+ )
209
+ print(ref.text)
210
+
211
+ response = QueryResponse().create_element(
212
+ "urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success",
213
+ "req-1",
214
+ )
215
+ print(response.element.tag)
216
+ ```
217
+
218
+ ---
219
+
201
220
  ### Функція `deep_get()` (`pyRegRep4.utils`)
202
221
 
203
222
  ```python
@@ -250,7 +269,7 @@ print(procedure) # [{"lang": "en", "value": "GetBirthCertificate"}]
250
269
  ```
251
270
  pyRegRep/
252
271
  ├── pyRegRep4/
253
- │ ├── __init__.py # Експорт: get_slot та типи слотів
272
+ │ ├── __init__.py # Експорт: get_slot, deep_get, Parsing, serialize_any_value_type
254
273
  │ ├── RIMElement.py # Класи слотів + фабрика get_slot()
255
274
  │ ├── RIMParsing.py # Парсер Parsing + serialize()
256
275
  │ ├── utils.py # deep_get() для вкладених словників
@@ -337,4 +356,4 @@ MIT License — див. файл [LICENSE](LICENSE)
337
356
 
338
357
  ---
339
358
 
340
- **Версія:** 12 · **Оновлено:** 2026-04-12
359
+ **Версія:** 13 · **Оновлено:** 2026-04-14
@@ -1,3 +1,27 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyRegRep
3
+ Version: 14
4
+ Summary: Бібліотека для роботи з реєстрами та репозитаріями в Україні
5
+ Author-email: Andrii Shapovalov <mt.andrey@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/AndreyShapovalovVN/pyRegRep
8
+ Project-URL: Repository, https://github.com/AndreyShapovalovVN/pyRegRep.git
9
+ Project-URL: Issues, https://github.com/AndreyShapovalovVN/pyRegRep/issues
10
+ Keywords: registry,repositories,ukraine
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: lxml>=5.2.1
22
+ Requires-Dist: xmltodict>=0.13.0
23
+ Dynamic: license-file
24
+
1
25
  # pyRegRep
2
26
 
3
27
  Бібліотека Python для парсування та обробки XML документів у форматі RIM (Registry Information Model) / ebXML.
@@ -14,6 +38,7 @@
14
38
  - ✅ Обробка всіх типів значень: Boolean, String, Integer, DateTime, Collection, InternationalString, AnyValue
15
39
  - ✅ Серіалізація даних у зручний Python-формат (`dict`)
16
40
  - ✅ Фабрика слотів `get_slot()` — програмне створення RIM-слотів за типом
41
+ - ✅ Builder-класи для елементів `RegistryObject`, `RepositoryItemRef`, `QueryResponse`, `Classification`
17
42
  - ✅ Серіалізація `AnyValueType` через `xmltodict` (параметр `any_type=True`)
18
43
  - ✅ Підтримка вкладених колекцій та складних структур
19
44
  - ✅ Безпечний доступ до вкладених даних через `deep_get()`
@@ -184,6 +209,38 @@ except ValueError as e:
184
209
 
185
210
  ---
186
211
 
212
+ ### Builder-класи XML елементів (`pyRegRep4.RIMElement`)
213
+
214
+ Публічні класи для побудови типових елементів RIM/query:
215
+
216
+ - `RegistryObject`
217
+ - `RepositoryItemRef`
218
+ - `QueryResponse`
219
+ - `Classification`
220
+
221
+ Усі класи мають однаковий базовий контракт:
222
+ - `element` — повертає `etree._Element` (або `ValueError`, якщо елемент ще не створено)
223
+ - `text` — серіалізований XML (`bytes`)
224
+ - `create_element(...)` — будує XML елемент і повертає `self` (chain-style)
225
+
226
+ ```python
227
+ from pyRegRep4.RIMElement import RepositoryItemRef, QueryResponse
228
+
229
+ ref = RepositoryItemRef().create_element(
230
+ "https://example.org/document.xml",
231
+ "Document",
232
+ )
233
+ print(ref.text)
234
+
235
+ response = QueryResponse().create_element(
236
+ "urn:oasis:names:tc:ebxml-regrep:ResponseStatusType:Success",
237
+ "req-1",
238
+ )
239
+ print(response.element.tag)
240
+ ```
241
+
242
+ ---
243
+
187
244
  ### Функція `deep_get()` (`pyRegRep4.utils`)
188
245
 
189
246
  ```python
@@ -236,7 +293,7 @@ print(procedure) # [{"lang": "en", "value": "GetBirthCertificate"}]
236
293
  ```
237
294
  pyRegRep/
238
295
  ├── pyRegRep4/
239
- │ ├── __init__.py # Експорт: get_slot та типи слотів
296
+ │ ├── __init__.py # Експорт: get_slot, deep_get, Parsing, serialize_any_value_type
240
297
  │ ├── RIMElement.py # Класи слотів + фабрика get_slot()
241
298
  │ ├── RIMParsing.py # Парсер Parsing + serialize()
242
299
  │ ├── utils.py # deep_get() для вкладених словників
@@ -323,4 +380,4 @@ MIT License — див. файл [LICENSE](LICENSE)
323
380
 
324
381
  ---
325
382
 
326
- **Версія:** 12 · **Оновлено:** 2026-04-12
383
+ **Версія:** 13 · **Оновлено:** 2026-04-14
@@ -1,7 +1,6 @@
1
1
  LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
- setup.py
5
4
  pyRegRep.egg-info/PKG-INFO
6
5
  pyRegRep.egg-info/SOURCES.txt
7
6
  pyRegRep.egg-info/dependency_links.txt
@@ -1,6 +1,5 @@
1
1
  """Namespace management for RIM/ebXML documents."""
2
2
 
3
- from typing import Dict
4
3
 
5
4
 
6
5
  class NS:
@@ -13,12 +12,13 @@ class NS:
13
12
  "rs": "urn:oasis:names:tc:ebxml-regrep:xsd:rs:4.0",
14
13
  "xsi": "http://www.w3.org/2001/XMLSchema-instance",
15
14
  "xsd": "http://www.w3.org/2001/XMLSchema",
15
+ "xlink": "http://www.w3.org/1999/xlink",
16
16
  "xml": "http://www.w3.org/XML/1998/namespace",
17
17
  }
18
18
 
19
19
  def __init__(self):
20
20
  """Initialize namespace handling."""
21
- self._ns: Dict[str, str] = self.DEFAULT_NAMESPACES.copy() # type: ignore
21
+ self._ns: dict[str, str] = self.DEFAULT_NAMESPACES.copy() # type: ignore
22
22
 
23
23
  def _tname(self, prefix: str, localname: str) -> str:
24
24
  """
@@ -36,7 +36,7 @@ class NS:
36
36
 
37
37
  return f"{{{self._ns[prefix]}}}{localname}"
38
38
 
39
- def _extract_namespaces(self) -> Dict[str, str]:
39
+ def _extract_namespaces(self) -> dict[str, str]:
40
40
  """
41
41
  Extract namespaces from the document.
42
42
  Override this method in subclasses if needed.
@@ -47,7 +47,7 @@ class NS:
47
47
  return self._ns.copy()
48
48
 
49
49
  @property
50
- def ns(self) -> Dict[str, str]:
50
+ def ns(self) -> dict[str, str]:
51
51
  """Get the namespace mappings."""
52
52
  return self._ns.copy()
53
53
 
@@ -1,6 +1,8 @@
1
1
  import datetime
2
2
  import logging
3
- from typing import Any
3
+ from abc import ABC, abstractmethod
4
+ from collections.abc import Callable
5
+ from typing import Any, cast
4
6
 
5
7
  from lxml import etree
6
8
 
@@ -8,14 +10,41 @@ from pyRegRep4.NS import NS
8
10
 
9
11
  _logger = logging.getLogger(__name__)
10
12
 
13
+ __all__ = [
14
+ "get_slot",
15
+ "RegistryObject",
16
+ "RepositoryItemRef",
17
+ "QueryResponse",
18
+ "Classification"
19
+ ]
20
+
21
+
22
+ class _ElementContainer(NS):
23
+ """Internal base for simple classes that wrap a single XML element."""
24
+
25
+ def __init__(self) -> None:
26
+ super().__init__()
27
+ self._element: etree._Element | None = None
28
+
29
+ @property
30
+ def element(self) -> etree._Element:
31
+ if self._element is None:
32
+ raise ValueError("XML element is not initialized")
33
+ return self._element
34
+
35
+ @property
36
+ def text(self) -> bytes:
37
+ return cast(bytes, etree.tostring(self.element, encoding="utf-8"))
38
+
39
+
40
+ class Xml(ABC, _ElementContainer):
41
+ """Base class for slot-like XML objects that carry value and name."""
11
42
 
12
- class Xml(NS):
13
43
  def __init__(self, value: Any):
14
44
  super().__init__()
15
45
  self._name: str = ""
16
46
  self.value: Any = value
17
- self._element: etree._Element | None = None
18
- self._create_element()
47
+ self.create_element()
19
48
 
20
49
  @property
21
50
  def name(self) -> str:
@@ -25,24 +54,15 @@ class Xml(NS):
25
54
  def name(self, value: str) -> None:
26
55
  self._name = value
27
56
  if self._element is not None:
28
- self._create_element()
57
+ self.create_element()
29
58
 
30
- def _create_element(self):
59
+ @abstractmethod
60
+ def create_element(self):
31
61
  ...
32
62
 
33
- @property
34
- def element(self) -> etree._Element:
35
- if self._element is None:
36
- raise ValueError("XML element is not initialized")
37
- return self._element
38
-
39
- @property
40
- def text(self) -> bytes:
41
- return etree.tostring(self.element)
42
-
43
63
 
44
64
  class _BooleanValueType(Xml):
45
- def _create_element(self):
65
+ def create_element(self):
46
66
  self._element = etree.Element(
47
67
  self._tname("rim", "Slot"), nsmap=self._ns,
48
68
  attrib={"name": self.name}
@@ -56,7 +76,7 @@ class _BooleanValueType(Xml):
56
76
 
57
77
 
58
78
  class _StringValueType(Xml):
59
- def _create_element(self):
79
+ def create_element(self):
60
80
  self._element = etree.Element(
61
81
  self._tname("rim", "Slot"), nsmap=self._ns,
62
82
  attrib={"name": self.name}
@@ -70,7 +90,7 @@ class _StringValueType(Xml):
70
90
 
71
91
 
72
92
  class _TimeStamp(Xml):
73
- def _create_element(self):
93
+ def create_element(self):
74
94
  self._element = etree.Element(
75
95
  self._tname("rim", "Slot"), nsmap=self._ns,
76
96
  attrib={"name": self.name}
@@ -87,7 +107,7 @@ class _TimeStamp(Xml):
87
107
 
88
108
 
89
109
  class _CollectionValueType(Xml):
90
- def _create_element(self):
110
+ def create_element(self):
91
111
  self._element = etree.Element(
92
112
  self._tname("rim", "Slot"), nsmap=self._ns,
93
113
  attrib={"name": self.name}
@@ -110,7 +130,7 @@ class _CollectionValueType(Xml):
110
130
 
111
131
 
112
132
  class _AnyValueType(Xml):
113
- def _create_element(self):
133
+ def create_element(self):
114
134
  self._element = etree.Element(
115
135
  self._tname("rim", "Slot"), nsmap=self._ns,
116
136
  attrib={"name": self.name}
@@ -124,7 +144,7 @@ class _AnyValueType(Xml):
124
144
 
125
145
 
126
146
  class _InternationalStringValueType(Xml):
127
- def _create_element(self):
147
+ def create_element(self):
128
148
  self._element = etree.Element(
129
149
  self._tname("rim", "Slot"), nsmap=self._ns,
130
150
  attrib={"name": self.name}
@@ -144,7 +164,10 @@ class _InternationalStringValueType(Xml):
144
164
  if element is not None:
145
165
  v.append(element)
146
166
  else:
147
- _logger.warning(f"Unsupported item type in InternationalStringValueType: {type(item)}")
167
+ _logger.warning(
168
+ "Unsupported item type in InternationalStringValueType: %s",
169
+ type(item),
170
+ )
148
171
  else:
149
172
  if isinstance(self.value, etree._Element):
150
173
  v.append(self.value)
@@ -226,7 +249,7 @@ def get_slot(name: str, slot_type: str, value: Any) -> Xml:
226
249
  ... except ValueError as e:
227
250
  ... print(f"Error: {e}")
228
251
  """
229
- slot_type_map = {
252
+ slot_type_map: dict[str, Callable[[Any], Xml]] = {
230
253
  "StringValueType": _StringValueType,
231
254
  "BooleanValueType": _BooleanValueType,
232
255
  "DateTimeValueType": _TimeStamp,
@@ -237,8 +260,72 @@ def get_slot(name: str, slot_type: str, value: Any) -> Xml:
237
260
 
238
261
  slot_class = slot_type_map.get(slot_type)
239
262
  if slot_class is None:
240
- raise ValueError(f"Невідомий тип слота: {slot_type}. Підтримувані типи: {list(slot_type_map.keys())}")
263
+ supported_types = list(slot_type_map.keys())
264
+ raise ValueError(
265
+ f"Невідомий тип слота: {slot_type}. Підтримувані типи: {supported_types}"
266
+ )
241
267
 
242
268
  slot = slot_class(value)
243
269
  slot.name = name
244
270
  return slot
271
+
272
+
273
+ class RegistryObject(_ElementContainer):
274
+ """Builder for rim:RegistryObject elements."""
275
+
276
+ def create_element(self, type: str, id: str):
277
+ self._element = etree.Element(
278
+ self._tname("rim", "RegistryObject"),
279
+ nsmap=self._ns,
280
+ attrib={
281
+ self._tname("xsi", "type"): type,
282
+ "id": id
283
+ }
284
+ )
285
+ return self
286
+
287
+
288
+ class RepositoryItemRef(_ElementContainer):
289
+ """Builder for rim:RepositoryItemRef elements."""
290
+
291
+ def create_element(self, href: str, title: str | None = None):
292
+ attr = {self._tname("xlink", "href"): href}
293
+ if title is not None:
294
+ attr["title"] = title
295
+
296
+ self._element = etree.Element(
297
+ self._tname("rim", "RepositoryItemRef"),
298
+ nsmap=self._ns,
299
+ attrib=attr
300
+ )
301
+ return self
302
+
303
+
304
+ class QueryResponse(_ElementContainer):
305
+ """Builder for query:QueryResponse elements."""
306
+
307
+ def create_element(self, status: str, request_id: str):
308
+ self._element = etree.Element(
309
+ self._tname("query", "QueryResponse"), nsmap=self._ns,
310
+ attrib={
311
+ 'status': status,
312
+ 'requestId': request_id,
313
+ }
314
+ )
315
+ return self
316
+
317
+
318
+ class Classification(_ElementContainer):
319
+ """Builder for rim:Classification elements."""
320
+
321
+ def create_element(self, id: str, classification_scheme: str, classification_node: str):
322
+ self._element = etree.Element(
323
+ self._tname("rim", "Classification"),
324
+ nsmap=self._ns,
325
+ attrib={
326
+ "id": id,
327
+ "classificationScheme": classification_scheme,
328
+ "classificationNode": classification_node
329
+ }
330
+ )
331
+ return self