dimp 2.4.2__tar.gz → 2.4.3__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 (47) hide show
  1. {dimp-2.4.2 → dimp-2.4.3}/PKG-INFO +6 -5
  2. {dimp-2.4.2 → dimp-2.4.3}/README.md +5 -4
  3. {dimp-2.4.2 → dimp-2.4.3}/dimp/__init__.py +6 -0
  4. {dimp-2.4.2 → dimp-2.4.3}/dimp/crypto/algorithms.py +4 -0
  5. {dimp-2.4.2 → dimp-2.4.3}/dimp/dkd/base.py +7 -6
  6. {dimp-2.4.2 → dimp-2.4.3}/dimp/dkd/envelope.py +5 -3
  7. {dimp-2.4.2 → dimp-2.4.3}/dimp/dkd/instant.py +9 -7
  8. {dimp-2.4.2 → dimp-2.4.3}/dimp/dkd/reliable.py +5 -3
  9. {dimp-2.4.2 → dimp-2.4.3}/dimp/dkd/secure.py +9 -7
  10. {dimp-2.4.2 → dimp-2.4.3}/dimp/format/__init__.py +6 -0
  11. {dimp-2.4.2 → dimp-2.4.3}/dimp/format/data.py +2 -0
  12. {dimp-2.4.2 → dimp-2.4.3}/dimp/format/duri.py +7 -6
  13. {dimp-2.4.2 → dimp-2.4.3}/dimp/format/embed.py +6 -5
  14. {dimp-2.4.2 → dimp-2.4.3}/dimp/format/file.py +7 -5
  15. {dimp-2.4.2 → dimp-2.4.3}/dimp/format/file_wrapper.py +7 -5
  16. {dimp-2.4.2 → dimp-2.4.3}/dimp/format/pnf.py +12 -9
  17. {dimp-2.4.2 → dimp-2.4.3}/dimp/format/pnf_wrapper.py +12 -9
  18. {dimp-2.4.2 → dimp-2.4.3}/dimp/mkm/docs.py +7 -5
  19. {dimp-2.4.2 → dimp-2.4.3}/dimp/mkm/document.py +10 -6
  20. {dimp-2.4.2 → dimp-2.4.3}/dimp/mkm/meta.py +9 -7
  21. {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/assets.py +5 -3
  22. {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/base.py +9 -7
  23. {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/commands.py +7 -4
  24. {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/contents.py +10 -8
  25. {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/files.py +15 -13
  26. {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/forward.py +11 -9
  27. {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/groups.py +9 -8
  28. {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/quote.py +12 -9
  29. {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/receipt.py +6 -4
  30. {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/types.py +3 -0
  31. {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/version.py +4 -0
  32. {dimp-2.4.2 → dimp-2.4.3}/dimp.egg-info/PKG-INFO +6 -5
  33. dimp-2.4.3/dimp.egg-info/requires.txt +2 -0
  34. {dimp-2.4.2 → dimp-2.4.3}/setup.py +3 -3
  35. dimp-2.4.2/dimp.egg-info/requires.txt +0 -2
  36. {dimp-2.4.2 → dimp-2.4.3}/LICENSE +0 -0
  37. {dimp-2.4.2 → dimp-2.4.3}/dimp/crypto/__init__.py +0 -0
  38. {dimp-2.4.2 → dimp-2.4.3}/dimp/dkd/__init__.py +0 -0
  39. {dimp-2.4.2 → dimp-2.4.3}/dimp/ext/__init__.py +0 -0
  40. {dimp-2.4.2 → dimp-2.4.3}/dimp/format/base.py +0 -0
  41. {dimp-2.4.2 → dimp-2.4.3}/dimp/mkm/__init__.py +0 -0
  42. {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/__init__.py +0 -0
  43. {dimp-2.4.2 → dimp-2.4.3}/dimp/protocol/docs.py +0 -0
  44. {dimp-2.4.2 → dimp-2.4.3}/dimp.egg-info/SOURCES.txt +0 -0
  45. {dimp-2.4.2 → dimp-2.4.3}/dimp.egg-info/dependency_links.txt +0 -0
  46. {dimp-2.4.2 → dimp-2.4.3}/dimp.egg-info/top_level.txt +0 -0
  47. {dimp-2.4.2 → dimp-2.4.3}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dimp
3
- Version: 2.4.2
3
+ Version: 2.4.3
4
4
  Summary: Decentralized Instant Messaging Protocol
5
5
  Home-page: https://github.com/dimchat/core-py
6
6
  Author: Albert Moky
@@ -47,7 +47,8 @@ License-File: LICENSE
47
47
  ```python
48
48
  from abc import ABC, abstractmethod
49
49
  from enum import IntEnum
50
- from typing import Optional, Dict
50
+ from collections.abc import Mapping
51
+ from typing import Optional
51
52
 
52
53
  from dimp import *
53
54
 
@@ -150,7 +151,7 @@ class HandshakeCommand(Command, ABC):
150
151
 
151
152
  class BaseHandshakeCommand(BaseCommand, HandshakeCommand):
152
153
 
153
- def __init__(self, content: Dict = None, title: str = None, session: str = None):
154
+ def __init__(self, content: Mapping = None, title: str = None, session: str = None):
154
155
  if content is None:
155
156
  # 1. new command with title & session key
156
157
  assert title is not None, 'handshake command error: %s' % session
@@ -250,14 +251,14 @@ class CustomizedContent(Content, ABC):
250
251
  ```
251
252
 
252
253
  ```python
253
- from typing import Dict
254
+ from collections.abc import Mapping
254
255
 
255
256
  from dimp import *
256
257
 
257
258
 
258
259
  class AppCustomizedContent(BaseContent, AppContent, CustomizedContent):
259
260
 
260
- def __init__(self, content: Dict = None,
261
+ def __init__(self, content: Mapping = None,
261
262
  msg_type: str = None,
262
263
  app: str = None, mod: str = None, act: str = None):
263
264
  if content is None:
@@ -33,7 +33,8 @@
33
33
  ```python
34
34
  from abc import ABC, abstractmethod
35
35
  from enum import IntEnum
36
- from typing import Optional, Dict
36
+ from collections.abc import Mapping
37
+ from typing import Optional
37
38
 
38
39
  from dimp import *
39
40
 
@@ -136,7 +137,7 @@ class HandshakeCommand(Command, ABC):
136
137
 
137
138
  class BaseHandshakeCommand(BaseCommand, HandshakeCommand):
138
139
 
139
- def __init__(self, content: Dict = None, title: str = None, session: str = None):
140
+ def __init__(self, content: Mapping = None, title: str = None, session: str = None):
140
141
  if content is None:
141
142
  # 1. new command with title & session key
142
143
  assert title is not None, 'handshake command error: %s' % session
@@ -236,14 +237,14 @@ class CustomizedContent(Content, ABC):
236
237
  ```
237
238
 
238
239
  ```python
239
- from typing import Dict
240
+ from collections.abc import Mapping
240
241
 
241
242
  from dimp import *
242
243
 
243
244
 
244
245
  class AppCustomizedContent(BaseContent, AppContent, CustomizedContent):
245
246
 
246
- def __init__(self, content: Dict = None,
247
+ def __init__(self, content: Mapping = None,
247
248
  msg_type: str = None,
248
249
  app: str = None, mod: str = None, act: str = None):
249
250
  if content is None:
@@ -44,6 +44,12 @@ __all__ = [
44
44
 
45
45
  'Singleton',
46
46
 
47
+ 'final',
48
+
49
+ 'Mapping', 'MutableMapping',
50
+ 'StrMap', 'MutableStrMap',
51
+ 'AnyList', 'StrList',
52
+
47
53
  'URI', 'DateTime',
48
54
 
49
55
  'Converter', 'DataConverter', 'BaseConverter',
@@ -23,7 +23,10 @@
23
23
  # SOFTWARE.
24
24
  # ==============================================================================
25
25
 
26
+ from mkm.types import final
26
27
 
28
+
29
+ @final
27
30
  class AsymmetricAlgorithms:
28
31
  """ Algorithms for Asymmetric Key """
29
32
 
@@ -31,6 +34,7 @@ class AsymmetricAlgorithms:
31
34
  ECC = 'ECC'
32
35
 
33
36
 
37
+ @final
34
38
  class SymmetricAlgorithms:
35
39
  """ Algorithms for Symmetric Key """
36
40
 
@@ -40,7 +40,7 @@
40
40
  | time | | time | | time |
41
41
  | | | | | |
42
42
  | content | | data | | data |
43
- +-------------+ | key/keys | | key/keys |
43
+ +-------------+ | keys | | keys |
44
44
  +------------+ | signature |
45
45
  +--------------+
46
46
  Algorithm:
@@ -49,22 +49,23 @@
49
49
  signature = sender.private_key.sign(data)
50
50
  """
51
51
 
52
-
53
- from typing import Optional, Dict
52
+ from typing import Optional
54
53
 
55
54
  from mkm.types import DateTime
55
+ from mkm.types import StrMap
56
56
  from mkm.types import Dictionary
57
+
57
58
  from mkm.protocol import ID
58
59
  from dkd.protocol import Envelope, Message
59
60
 
60
61
 
61
62
  class BaseMessage(Dictionary, Message):
62
63
 
63
- def __init__(self, msg: Dict = None, head: Envelope = None):
64
+ def __init__(self, msg: StrMap = None, head: Envelope = None):
64
65
  if msg is None:
65
66
  # 1. new message with envelope
66
67
  assert head is not None, 'message envelope should not be empty'
67
- msg = head.to_dict()
68
+ msg = head.to_map()
68
69
  else:
69
70
  # 2. message info from network
70
71
  assert head is None, f'params error: {msg}, {head}'
@@ -77,7 +78,7 @@ class BaseMessage(Dictionary, Message):
77
78
  env = self.__envelope
78
79
  if env is None:
79
80
  # let envelope share the same dictionary with message
80
- env = Envelope.parse(envelope=super().to_dict())
81
+ env = Envelope.parse(envelope=super().to_map())
81
82
  self.__envelope = env
82
83
  return env
83
84
 
@@ -28,10 +28,12 @@
28
28
  # SOFTWARE.
29
29
  # ==============================================================================
30
30
 
31
- from typing import Optional, Dict
31
+ from typing import Optional
32
32
 
33
33
  from mkm.types import DateTime
34
+ from mkm.types import StrMap
34
35
  from mkm.types import Dictionary
36
+
35
37
  from mkm.protocol import ID, ANYONE
36
38
  from dkd.protocol import Envelope
37
39
 
@@ -52,7 +54,7 @@ from dkd.protocol import Envelope
52
54
 
53
55
  class MessageEnvelope(Dictionary, Envelope):
54
56
 
55
- def __init__(self, envelope: Dict = None,
57
+ def __init__(self, envelope: StrMap = None,
56
58
  sender: ID = None, receiver: Optional[ID] = None, time: Optional[DateTime] = None):
57
59
  if envelope is None:
58
60
  # 1. new envelope with sender, receiver & time
@@ -83,7 +85,7 @@ class MessageEnvelope(Dictionary, Envelope):
83
85
  if did is None:
84
86
  did = self.get('sender')
85
87
  did = ID.parse(identifier=did)
86
- assert did is not None, 'message sender error: %s' % super().to_dict()
88
+ assert did is not None, 'message sender error: %s' % super().to_map()
87
89
  self.__sender = did
88
90
  return did
89
91
 
@@ -28,9 +28,11 @@
28
28
  # SOFTWARE.
29
29
  # ==============================================================================
30
30
 
31
- from typing import Optional, Dict
31
+ from typing import Optional
32
32
 
33
33
  from mkm.types import DateTime
34
+ from mkm.types import StrMap, MutableStrMap
35
+
34
36
  from mkm.protocol import ID
35
37
  from dkd.protocol import Content
36
38
  from dkd.protocol import Envelope
@@ -57,13 +59,13 @@ from .base import BaseMessage
57
59
 
58
60
  class PlainMessage(BaseMessage, InstantMessage):
59
61
 
60
- def __init__(self, msg: Dict = None,
62
+ def __init__(self, msg: StrMap = None,
61
63
  head: Envelope = None, body: Content = None):
62
64
  if msg is None:
63
65
  # 1. new instant message with envelope & content
64
66
  assert head is not None and body is not None, f'instant message error: {head}, {body}'
65
67
  super().__init__(None, head)
66
- # self['content'] = body.to_dict()
68
+ # self['content'] = body.to_map()
67
69
  else:
68
70
  # 2. message info from network
69
71
  assert head is None and body is None, f'params error: {msg}, {head}, {body}'
@@ -93,7 +95,7 @@ class PlainMessage(BaseMessage, InstantMessage):
93
95
  if body is None:
94
96
  info = self.get('content')
95
97
  body = Content.parse(content=info)
96
- assert body is not None, f'message content error: {self.to_dict()}'
98
+ assert body is not None, f'message content error: {self.to_map()}'
97
99
  self.__content = body
98
100
  return body
99
101
 
@@ -104,10 +106,10 @@ class PlainMessage(BaseMessage, InstantMessage):
104
106
  self.__content = value
105
107
 
106
108
  # Override
107
- def to_dict(self) -> Dict:
109
+ def to_map(self) -> MutableStrMap:
108
110
  # serialize 'content'
109
111
  body = self.__content
110
112
  if body is not None and self.get('content') is None:
111
- self['content'] = body.to_dict()
113
+ self['content'] = body.to_map()
112
114
  # OK
113
- return super().to_dict()
115
+ return super().to_map()
@@ -28,9 +28,11 @@
28
28
  # SOFTWARE.
29
29
  # ==============================================================================
30
30
 
31
- from typing import Optional, Dict
31
+ from typing import Optional
32
32
 
33
+ from mkm.types import StrMap
33
34
  from mkm.format import TransportableData
35
+
34
36
  from dkd.protocol import ReliableMessage
35
37
 
36
38
  from .secure import EncryptedMessage
@@ -48,7 +50,7 @@ from .secure import EncryptedMessage
48
50
  "receiver" : "hulk@yyy",
49
51
  "time" : 123.45,
50
52
 
51
- //-- content data and key/keys
53
+ //-- content data and keys
52
54
  "data" : "...", // base64_encode( symmetric_encrypt(content))
53
55
  "keys" : {
54
56
  "ID1" : "key1", // base64_encode(asymmetric_encrypt(password))
@@ -62,7 +64,7 @@ from .secure import EncryptedMessage
62
64
 
63
65
  class NetworkMessage(EncryptedMessage, ReliableMessage):
64
66
 
65
- def __init__(self, msg: Dict):
67
+ def __init__(self, msg: StrMap):
66
68
  super().__init__(msg=msg)
67
69
  # lazy
68
70
  self.__signature: Optional[TransportableData] = None
@@ -28,9 +28,11 @@
28
28
  # SOFTWARE.
29
29
  # ==============================================================================
30
30
 
31
- from typing import Optional, Dict
31
+ from typing import Optional
32
32
 
33
+ from mkm.types import Mapping, StrMap
33
34
  from mkm.format import TransportableData
35
+
34
36
  from dkd.protocol import SecureMessage
35
37
 
36
38
  from ..format import PlainData
@@ -49,7 +51,7 @@ from .base import BaseMessage
49
51
  "receiver" : "hulk@yyy",
50
52
  "time" : 123.45,
51
53
 
52
- //-- content data and key/keys
54
+ //-- content data and keys
53
55
  "data" : "...", // base64_encode( symmetric_encrypt(content))
54
56
  "keys" : {
55
57
  "ID1" : "key1", // base64_encode(asymmetric_encrypt(password))
@@ -61,11 +63,11 @@ from .base import BaseMessage
61
63
 
62
64
  class EncryptedMessage(BaseMessage, SecureMessage):
63
65
 
64
- def __init__(self, msg: Dict):
66
+ def __init__(self, msg: StrMap):
65
67
  super().__init__(msg=msg)
66
68
  # lazy
67
69
  self.__data: Optional[TransportableData] = None
68
- self.__keys: Optional[Dict] = None
70
+ self.__keys: Optional[StrMap] = None
69
71
 
70
72
  @property # Override
71
73
  def data(self) -> TransportableData:
@@ -73,7 +75,7 @@ class EncryptedMessage(BaseMessage, SecureMessage):
73
75
  if ted is None:
74
76
  text = self.get('data')
75
77
  if text is None:
76
- assert False, 'message data not found: %s' % super().to_dict()
78
+ assert False, 'message data not found: %s' % super().to_map()
77
79
  elif not BaseMessage.is_broadcast(msg=self):
78
80
  # message content had been encrypted by a symmetric key,
79
81
  # so the data should be encoded here (with algorithm 'base64' as default).
@@ -89,11 +91,11 @@ class EncryptedMessage(BaseMessage, SecureMessage):
89
91
  return ted
90
92
 
91
93
  @property # Override
92
- def encrypted_keys(self) -> Optional[Dict]:
94
+ def encrypted_keys(self) -> Optional[StrMap]:
93
95
  keys = self.__keys
94
96
  if keys is None:
95
97
  keys = self.get('keys')
96
- if isinstance(keys, Dict):
98
+ if isinstance(keys, Mapping):
97
99
  self.__keys = keys
98
100
  else:
99
101
  assert keys is None, f'message keys error: {keys}'
@@ -46,6 +46,12 @@ __all__ = [
46
46
 
47
47
  'Singleton',
48
48
 
49
+ 'final',
50
+
51
+ 'Mapping', 'MutableMapping',
52
+ 'StrMap', 'MutableStrMap',
53
+ 'AnyList', 'StrList',
54
+
49
55
  'URI', 'DateTime',
50
56
 
51
57
  'Converter', 'DataConverter', 'BaseConverter',
@@ -25,6 +25,7 @@
25
25
 
26
26
  from typing import Optional
27
27
 
28
+ from mkm.types import final
28
29
  from mkm.format import base64_encode, base64_decode
29
30
  from mkm.format import utf8_encode, utf8_decode
30
31
 
@@ -70,6 +71,7 @@ class Base64Data(BaseData):
70
71
  return Base64Data(string=string, binary=binary)
71
72
 
72
73
 
74
+ @final
73
75
  class PlainData(BaseData):
74
76
  """ UTF-8 encoding """
75
77
 
@@ -23,7 +23,8 @@
23
23
  # SOFTWARE.
24
24
  # ==============================================================================
25
25
 
26
- from typing import Optional, Dict
26
+ from typing import Optional
27
+ from typing import Mapping, MutableMapping
27
28
 
28
29
  from mkm.format import base64_decode, utf8_encode
29
30
 
@@ -39,7 +40,7 @@ from mkm.format import base64_decode, utf8_encode
39
40
 
40
41
  class Header:
41
42
 
42
- def __init__(self, mime_type: str, encoding: str = None, extra: Dict[str, str] = None):
43
+ def __init__(self, mime_type: str, encoding: str = None, extra: Mapping[str, str] = None):
43
44
  super().__init__()
44
45
  self.__mime_type = mime_type
45
46
  self.__encoding = encoding
@@ -58,7 +59,7 @@ class Header:
58
59
  return self.__encoding
59
60
 
60
61
  @property
61
- def extra(self) -> Optional[Dict[str, str]]:
62
+ def extra(self) -> Optional[Mapping[str, str]]:
62
63
  """ extra parameters """
63
64
  return self.__extra
64
65
 
@@ -78,7 +79,7 @@ class Header:
78
79
  else:
79
80
  name = name.lower()
80
81
  # get value by name in lowercase
81
- return extra[name]
82
+ return extra.get(name)
82
83
 
83
84
  # Override
84
85
  def __str__(self) -> str:
@@ -145,7 +146,7 @@ class Header:
145
146
  mime_type: str = None
146
147
  encoding: str = None
147
148
  # split extra info
148
- extra: Dict[str, str] = None
149
+ extra: MutableMapping[str, str] = None
149
150
  for item in array:
150
151
  if len(item) == 0:
151
152
  # assert False, f'header error: {uri}'
@@ -202,7 +203,7 @@ class DataURI:
202
203
  return self.__body
203
204
 
204
205
  @property
205
- def parameters(self) -> Optional[Dict[str, str]]:
206
+ def parameters(self) -> Optional[Mapping[str, str]]:
206
207
  """ extra parameters """
207
208
  return self.head.extra
208
209
 
@@ -23,7 +23,8 @@
23
23
  # SOFTWARE.
24
24
  # ==============================================================================
25
25
 
26
- from typing import Optional, Dict
26
+ from typing import Optional
27
+ from typing import Mapping
27
28
 
28
29
  from mkm.format import base64_encode
29
30
 
@@ -46,7 +47,7 @@ class EmbedData(BaseData):
46
47
  # lazy load
47
48
  self.__data_uri: Optional[DataURI] = None
48
49
  self.__mime_type: Optional[str] = None # default is "text/plain"
49
- self.__parameters: Optional[Dict[str, str]] = None
50
+ self.__parameters: Optional[Mapping[str, str]] = None
50
51
 
51
52
  @property
52
53
  def encoding(self) -> Optional[str]:
@@ -84,7 +85,7 @@ class EmbedData(BaseData):
84
85
  def header_value(self, name: str) -> Optional[str]:
85
86
  extra = self.parameters
86
87
  if extra is not None:
87
- value = extra[name]
88
+ value = extra.get(name)
88
89
  if value is not None:
89
90
  # charset
90
91
  # filename
@@ -98,7 +99,7 @@ class EmbedData(BaseData):
98
99
  # return self.encoding
99
100
 
100
101
  @property
101
- def parameters(self) -> Optional[Dict[str, str]]:
102
+ def parameters(self) -> Optional[Mapping[str, str]]:
102
103
  extra = self.__parameters
103
104
  if extra is not None:
104
105
  return extra
@@ -171,7 +172,7 @@ class EmbedData(BaseData):
171
172
 
172
173
  @classmethod
173
174
  def new(cls, string: Optional[str], binary: Optional[bytes],
174
- uri: DataURI = None, mime_type: str = None, parameters: Dict[str, str] = None):
175
+ uri: DataURI = None, mime_type: str = None, parameters: Mapping[str, str] = None):
175
176
  if parameters is None and uri is not None:
176
177
  parameters = uri.parameters
177
178
  embed = EmbedData(string=string, binary=binary)
@@ -24,10 +24,12 @@
24
24
  # ==============================================================================
25
25
 
26
26
  from abc import ABC, abstractmethod
27
- from typing import Optional, Union, Any, Dict
27
+ from typing import Optional, Union, Any
28
28
 
29
+ from mkm.types import StrMap, MutableStrMap
29
30
  from mkm.types import Mapper
30
31
  from mkm.types import URI
32
+
31
33
  from mkm.crypto import DecryptKey
32
34
  from mkm.format import TransportableResource
33
35
  from mkm.format import TransportableData
@@ -145,15 +147,15 @@ class TransportableFile(Mapper, TransportableResource, ABC):
145
147
 
146
148
  # Override
147
149
  @abstractmethod
148
- def to_dict(self) -> Dict:
150
+ def to_map(self) -> MutableStrMap:
149
151
  """ Serialize to map """
150
152
  raise NotImplementedError(
151
- f'Not implemented: {type(self).__module__}.{type(self).__name__}.to_dict()'
153
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.to_map()'
152
154
  )
153
155
 
154
156
  # Override
155
157
  @abstractmethod
156
- def serialize(self) -> Union[str, dict]:
158
+ def serialize(self) -> Union[str, StrMap]:
157
159
  """
158
160
  Serializes this PNF to a URL string or a map.
159
161
 
@@ -217,7 +219,7 @@ class TransportableFileFactory(ABC):
217
219
  )
218
220
 
219
221
  @abstractmethod
220
- def parse_transportable_file(self, pnf: Dict) -> Optional[TransportableFile]:
222
+ def parse_transportable_file(self, pnf: StrMap) -> Optional[TransportableFile]:
221
223
  """
222
224
  Parse map object to PNF
223
225
 
@@ -24,9 +24,11 @@
24
24
  # ==============================================================================
25
25
 
26
26
  from abc import ABC, abstractmethod
27
- from typing import Optional, Dict
27
+ from typing import Optional
28
28
 
29
29
  from mkm.types import URI
30
+ from mkm.types import StrMap, MutableStrMap
31
+
30
32
  from mkm.crypto import DecryptKey
31
33
  from mkm.format import TransportableData
32
34
  from mkm.ext import shared_format_extensions
@@ -35,10 +37,10 @@ from mkm.ext import shared_format_extensions
35
37
  class TransportableFileWrapper(ABC):
36
38
 
37
39
  @abstractmethod
38
- def to_dict(self) -> Dict:
40
+ def to_map(self) -> MutableStrMap:
39
41
  """ Serialize to map """
40
42
  raise NotImplementedError(
41
- f'Not implemented: {type(self).__module__}.{type(self).__name__}.to_dict()'
43
+ f'Not implemented: {type(self).__module__}.{type(self).__name__}.to_map()'
42
44
  )
43
45
 
44
46
  #
@@ -126,7 +128,7 @@ class TransportableFileWrapper(ABC):
126
128
  #
127
129
 
128
130
  @classmethod
129
- def create(cls, content: Dict,
131
+ def create(cls, content: StrMap,
130
132
  data: Optional[TransportableData] = None, filename: Optional[str] = None,
131
133
  url: Optional[URI] = None, password: Optional[DecryptKey] = None):
132
134
  factory = wrapper_factory()
@@ -139,7 +141,7 @@ class TransportableFileWrapperFactory(ABC):
139
141
  """ Wrapper factory """
140
142
 
141
143
  @abstractmethod
142
- def create_transportable_file_wrapper(self, content: Dict,
144
+ def create_transportable_file_wrapper(self, content: StrMap,
143
145
  data: Optional[TransportableData],
144
146
  filename: Optional[str],
145
147
  url: Optional[URI],
@@ -23,10 +23,12 @@
23
23
  # SOFTWARE.
24
24
  # ==============================================================================
25
25
 
26
- from typing import Optional, Union, Dict
26
+ from typing import Optional, Union
27
27
 
28
28
  from mkm.types import URI
29
+ from mkm.types import StrMap, MutableStrMap
29
30
  from mkm.types import Dictionary
31
+
30
32
  from mkm.crypto import DecryptKey
31
33
  from mkm.format import TransportableData
32
34
  from mkm.format import json_encode
@@ -37,13 +39,13 @@ from .file_wrapper import TransportableFileWrapper
37
39
 
38
40
  class PortableNetworkFile(Dictionary, TransportableFile):
39
41
 
40
- def __init__(self, dictionary: Optional[Dict],
42
+ def __init__(self, dictionary: Optional[StrMap],
41
43
  data: Optional[TransportableData] = None, filename: Optional[str] = None,
42
44
  url: Optional[URI] = None, password: Optional[DecryptKey] = None,
43
45
  wrapper: Optional[TransportableFileWrapper] = None):
44
46
  super().__init__(dictionary=dictionary)
45
47
  if wrapper is None:
46
- wrapper = TransportableFileWrapper.create(super().to_dict(),
48
+ wrapper = TransportableFileWrapper.create(super().to_map(),
47
49
  data=data, filename=filename,
48
50
  url=url, password=password)
49
51
  self.__wrapper = wrapper
@@ -53,7 +55,7 @@ class PortableNetworkFile(Dictionary, TransportableFile):
53
55
  def uri_string(self) -> Optional[str]:
54
56
  # serialize
55
57
  wrapper = self.__wrapper
56
- info = wrapper.to_dict()
58
+ info = wrapper.to_map()
57
59
  # check 'URL'
58
60
  remote = self.url
59
61
  if remote is not None and len(remote) > 0:
@@ -98,24 +100,25 @@ class PortableNetworkFile(Dictionary, TransportableFile):
98
100
  return uri_string
99
101
  # return JSON string
100
102
  wrapper = self.__wrapper
101
- info = wrapper.to_dict()
103
+ info = wrapper.to_map()
102
104
  return json_encode(info)
103
105
 
104
106
  # Override
105
- def to_dict(self) -> Dict:
107
+ def to_map(self) -> MutableStrMap:
106
108
  """ call wrapper to serialize 'data' & 'key" """
107
109
  wrapper = self.__wrapper
108
- return wrapper.to_dict()
110
+ return wrapper.to_map()
109
111
  # return self.__dictionary
110
112
 
111
113
  # Override
112
- def serialize(self) -> Union[str, dict]:
114
+ def serialize(self) -> Union[str, StrMap]:
113
115
  uri_string = self.uri_string
114
116
  if uri_string is not None:
115
117
  return uri_string
116
118
  # return inner map
117
119
  wrapper = self.__wrapper
118
- return wrapper.to_dict()
120
+ info = wrapper.to_map()
121
+ return dict(info)
119
122
 
120
123
  #
121
124
  # File data