MambuPy 2.0.0b50__tar.gz → 2.1.1__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 (159) hide show
  1. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/__init__.py +21 -4
  2. {MambuPy-2.0.0b50/mambupy → mambupy-2.1.1/MambuPy}/api/connector/rest.py +121 -31
  3. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/entities.py +14 -8
  4. {MambuPy-2.0.0b50/mambupy → mambupy-2.1.1/MambuPy}/mambuconfig.py +9 -0
  5. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/mambuutil.py +3 -3
  6. mambupy-2.1.1/MambuPy/rest/__init__.py +49 -0
  7. mambupy-2.1.1/MambuPy/rest/mambuactivity.py +87 -0
  8. mambupy-2.1.1/MambuPy/rest/mambubranch.py +122 -0
  9. mambupy-2.1.1/MambuPy/rest/mambucentre.py +104 -0
  10. mambupy-2.1.1/MambuPy/rest/mambuclient.py +317 -0
  11. mambupy-2.1.1/MambuPy/rest/mambugroup.py +372 -0
  12. mambupy-2.1.1/MambuPy/rest/mambuloan.py +687 -0
  13. mambupy-2.1.1/MambuPy/rest/mambuproduct.py +180 -0
  14. mambupy-2.1.1/MambuPy/rest/mamburepayment.py +99 -0
  15. mambupy-2.1.1/MambuPy/rest/mamburestutils.py +116 -0
  16. mambupy-2.1.1/MambuPy/rest/mamburoles.py +98 -0
  17. mambupy-2.1.1/MambuPy/rest/mambusaving.py +114 -0
  18. mambupy-2.1.1/MambuPy/rest/mambusavingfundingrepayment.py +94 -0
  19. mambupy-2.1.1/MambuPy/rest/mambusavingtransaction.py +163 -0
  20. mambupy-2.1.1/MambuPy/rest/mambustruct.py +1066 -0
  21. mambupy-2.1.1/MambuPy/rest/mambutask.py +163 -0
  22. mambupy-2.1.1/MambuPy/rest/mambutransaction.py +103 -0
  23. mambupy-2.1.1/MambuPy/rest/mambutransactionchannel.py +101 -0
  24. mambupy-2.1.1/MambuPy/rest/mambuuser.py +229 -0
  25. mambupy-2.1.1/MambuPy.egg-info/PKG-INFO +760 -0
  26. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy.egg-info/SOURCES.txt +39 -27
  27. mambupy-2.1.1/MambuPy.egg-info/requires.txt +30 -0
  28. mambupy-2.1.1/MambuPy.egg-info/top_level.txt +3 -0
  29. mambupy-2.1.1/PKG-INFO +760 -0
  30. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/__init__.py +21 -4
  31. {MambuPy-2.0.0b50/MambuPy → mambupy-2.1.1/mambupy}/api/connector/rest.py +121 -31
  32. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/entities.py +14 -8
  33. {MambuPy-2.0.0b50/MambuPy → mambupy-2.1.1/mambupy}/mambuconfig.py +9 -0
  34. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/mambuutil.py +3 -3
  35. mambupy-2.1.1/mambupy/rest/__init__.py +49 -0
  36. mambupy-2.1.1/mambupy/rest/mambuactivity.py +87 -0
  37. mambupy-2.1.1/mambupy/rest/mambubranch.py +122 -0
  38. mambupy-2.1.1/mambupy/rest/mambucentre.py +104 -0
  39. mambupy-2.1.1/mambupy/rest/mambuclient.py +317 -0
  40. mambupy-2.1.1/mambupy/rest/mambugroup.py +372 -0
  41. mambupy-2.1.1/mambupy/rest/mambuloan.py +687 -0
  42. mambupy-2.1.1/mambupy/rest/mambuproduct.py +180 -0
  43. mambupy-2.1.1/mambupy/rest/mamburepayment.py +99 -0
  44. mambupy-2.1.1/mambupy/rest/mamburestutils.py +116 -0
  45. mambupy-2.1.1/mambupy/rest/mamburoles.py +98 -0
  46. mambupy-2.1.1/mambupy/rest/mambusaving.py +114 -0
  47. mambupy-2.1.1/mambupy/rest/mambusavingfundingrepayment.py +94 -0
  48. mambupy-2.1.1/mambupy/rest/mambusavingtransaction.py +163 -0
  49. mambupy-2.1.1/mambupy/rest/mambustruct.py +1066 -0
  50. mambupy-2.1.1/mambupy/rest/mambutask.py +163 -0
  51. mambupy-2.1.1/mambupy/rest/mambutransaction.py +103 -0
  52. mambupy-2.1.1/mambupy/rest/mambutransactionchannel.py +101 -0
  53. mambupy-2.1.1/mambupy/rest/mambuuser.py +229 -0
  54. mambupy-2.1.1/pyproject.toml +49 -0
  55. MambuPy-2.0.0b50/MambuPy/rest1to2/__init__.py +0 -18
  56. MambuPy-2.0.0b50/MambuPy/rest1to2/mambubranch.py +0 -74
  57. MambuPy-2.0.0b50/MambuPy/rest1to2/mambucentre.py +0 -35
  58. MambuPy-2.0.0b50/MambuPy/rest1to2/mambuclient.py +0 -133
  59. MambuPy-2.0.0b50/MambuPy/rest1to2/mambugroup.py +0 -108
  60. MambuPy-2.0.0b50/MambuPy/rest1to2/mambuloan.py +0 -215
  61. MambuPy-2.0.0b50/MambuPy/rest1to2/mambuproduct.py +0 -34
  62. MambuPy-2.0.0b50/MambuPy/rest1to2/mamburepayment.py +0 -97
  63. MambuPy-2.0.0b50/MambuPy/rest1to2/mambustruct.py +0 -352
  64. MambuPy-2.0.0b50/MambuPy/rest1to2/mambutask.py +0 -64
  65. MambuPy-2.0.0b50/MambuPy/rest1to2/mambutransaction.py +0 -46
  66. MambuPy-2.0.0b50/MambuPy/rest1to2/mambuuser.py +0 -85
  67. MambuPy-2.0.0b50/MambuPy/utils/logging_config.py +0 -5
  68. MambuPy-2.0.0b50/MambuPy.egg-info/PKG-INFO +0 -49
  69. MambuPy-2.0.0b50/MambuPy.egg-info/requires.txt +0 -7
  70. MambuPy-2.0.0b50/MambuPy.egg-info/top_level.txt +0 -12
  71. MambuPy-2.0.0b50/PKG-INFO +0 -49
  72. MambuPy-2.0.0b50/mambupy/rest1to2/__init__.py +0 -18
  73. MambuPy-2.0.0b50/mambupy/rest1to2/mambubranch.py +0 -74
  74. MambuPy-2.0.0b50/mambupy/rest1to2/mambucentre.py +0 -35
  75. MambuPy-2.0.0b50/mambupy/rest1to2/mambuclient.py +0 -133
  76. MambuPy-2.0.0b50/mambupy/rest1to2/mambugroup.py +0 -108
  77. MambuPy-2.0.0b50/mambupy/rest1to2/mambuloan.py +0 -215
  78. MambuPy-2.0.0b50/mambupy/rest1to2/mambuproduct.py +0 -34
  79. MambuPy-2.0.0b50/mambupy/rest1to2/mamburepayment.py +0 -97
  80. MambuPy-2.0.0b50/mambupy/rest1to2/mambustruct.py +0 -352
  81. MambuPy-2.0.0b50/mambupy/rest1to2/mambutask.py +0 -64
  82. MambuPy-2.0.0b50/mambupy/rest1to2/mambutransaction.py +0 -46
  83. MambuPy-2.0.0b50/mambupy/rest1to2/mambuuser.py +0 -85
  84. MambuPy-2.0.0b50/mambupy/utils/logging_config.py +0 -5
  85. MambuPy-2.0.0b50/setup.py +0 -128
  86. {MambuPy-2.0.0b50 → mambupy-2.1.1}/LICENSE +0 -0
  87. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/__init__.py +0 -0
  88. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/classes.py +0 -0
  89. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/connector/__init__.py +0 -0
  90. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/connector/mambuconnector.py +0 -0
  91. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/interfaces.py +0 -0
  92. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/mambubranch.py +0 -0
  93. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/mambucentre.py +0 -0
  94. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/mambuclient.py +0 -0
  95. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/mambucustomfield.py +0 -0
  96. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/mambugroup.py +0 -0
  97. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/mambuloan.py +0 -0
  98. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/mambuproduct.py +0 -0
  99. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/mamburole.py +0 -0
  100. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/mambustruct.py +0 -0
  101. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/mambutask.py +0 -0
  102. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/mambutransaction.py +0 -0
  103. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/mambuuser.py +0 -0
  104. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/api/vos.py +0 -0
  105. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/mambugeturl.py +0 -0
  106. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/orm/__init__.py +0 -0
  107. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/orm/schema_activities.py +0 -0
  108. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/orm/schema_addresses.py +0 -0
  109. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/orm/schema_branches.py +0 -0
  110. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/orm/schema_centres.py +0 -0
  111. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/orm/schema_clients.py +0 -0
  112. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/orm/schema_customfields.py +0 -0
  113. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/orm/schema_dummies.py +0 -0
  114. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/orm/schema_groups.py +0 -0
  115. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/orm/schema_loans.py +0 -0
  116. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/orm/schema_mambu.py +0 -0
  117. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/orm/schema_orm.py +0 -0
  118. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/orm/schema_tasks.py +0 -0
  119. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/orm/schema_users.py +0 -0
  120. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/utils/__init__.py +0 -0
  121. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy/utils/userdeactivate.py +0 -0
  122. {MambuPy-2.0.0b50 → mambupy-2.1.1}/MambuPy.egg-info/dependency_links.txt +0 -0
  123. {MambuPy-2.0.0b50 → mambupy-2.1.1}/README.md +0 -0
  124. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/__init__.py +0 -0
  125. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/classes.py +0 -0
  126. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/connector/__init__.py +0 -0
  127. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/connector/mambuconnector.py +0 -0
  128. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/interfaces.py +0 -0
  129. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/mambubranch.py +0 -0
  130. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/mambucentre.py +0 -0
  131. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/mambuclient.py +0 -0
  132. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/mambucustomfield.py +0 -0
  133. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/mambugroup.py +0 -0
  134. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/mambuloan.py +0 -0
  135. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/mambuproduct.py +0 -0
  136. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/mamburole.py +0 -0
  137. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/mambustruct.py +0 -0
  138. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/mambutask.py +0 -0
  139. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/mambutransaction.py +0 -0
  140. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/mambuuser.py +0 -0
  141. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/api/vos.py +0 -0
  142. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/mambugeturl.py +0 -0
  143. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/orm/__init__.py +0 -0
  144. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/orm/schema_activities.py +0 -0
  145. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/orm/schema_addresses.py +0 -0
  146. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/orm/schema_branches.py +0 -0
  147. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/orm/schema_centres.py +0 -0
  148. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/orm/schema_clients.py +0 -0
  149. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/orm/schema_customfields.py +0 -0
  150. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/orm/schema_dummies.py +0 -0
  151. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/orm/schema_groups.py +0 -0
  152. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/orm/schema_loans.py +0 -0
  153. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/orm/schema_mambu.py +0 -0
  154. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/orm/schema_orm.py +0 -0
  155. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/orm/schema_tasks.py +0 -0
  156. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/orm/schema_users.py +0 -0
  157. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/utils/__init__.py +0 -0
  158. {MambuPy-2.0.0b50 → mambupy-2.1.1}/mambupy/utils/userdeactivate.py +0 -0
  159. {MambuPy-2.0.0b50 → mambupy-2.1.1}/setup.cfg +0 -0
@@ -5,17 +5,18 @@
5
5
 
6
6
  MambuPy.mambuconfig
7
7
  MambuPy.mambuutil
8
- MambuPy.rest
9
- MambuPy.orm
10
8
  MambuPy.api
11
9
  MambuPy.api.connector
10
+ MambuPy.orm
11
+ MambuPy.rest
12
12
 
13
13
 
14
14
  Currently, there are two different ways to access Mambu objects:
15
15
 
16
16
  1) Objects using `Mambu REST API
17
17
  <https://developer.mambu.com/customer/en/portal/articles/1162276-rest-apis-overview/>`_
18
- , they live at the :any:`MambuPy.rest` package
18
+ , they live at the :any:`MambuPy.api` package (the old-and-soon-to-be-deprecated,
19
+ V1-compatible code lives at :any:`MambuPy.rest`
19
20
 
20
21
  2) An ORM using a `DB backup retrieved from Mambu
21
22
  <https://support.mambu.com/docs/mambu-data-dictionary>`_
@@ -34,5 +35,21 @@ TODOS
34
35
  to achive TDD when implementing features or correcting bugs.
35
36
  """
36
37
 
37
- __version__ = "2.0.0b50"
38
+ import sys
39
+ from importlib.abc import MetaPathFinder
40
+ from importlib.util import spec_from_file_location
41
+
42
+ __version__ = "2.1.1"
38
43
  """The version of this module."""
44
+
45
+
46
+ class CaseInsensitiveFinder(MetaPathFinder):
47
+ def find_spec(self, fullname, path, target=None):
48
+ if fullname.lower() == "mambupy":
49
+ # Get the actual module file location
50
+ return spec_from_file_location(fullname, __file__)
51
+ return None
52
+
53
+
54
+ # Register the finder
55
+ sys.meta_path.insert(0, CaseInsensitiveFinder())
@@ -36,12 +36,82 @@ from MambuPy.mambuutil import (
36
36
  apiurl,
37
37
  apiuser,
38
38
  setup_logging,
39
+ activate_request_session_objects,
39
40
  )
40
41
 
41
42
 
42
43
  logger = setup_logging(__name__)
43
44
 
44
45
 
46
+ def _configure_retry_strategy(session, retries=5):
47
+ """Configure retry strategy for a session.
48
+
49
+ Args:
50
+ session (requests.Session): The session to configure
51
+ retries (int, optional): Number of retries. Defaults to 5.
52
+ """
53
+ retry_strategy = Retry(
54
+ total=retries,
55
+ status_forcelist=[429, 500, 502, 503, 504],
56
+ backoff_factor=1,
57
+ allowed_methods=[
58
+ "HEAD",
59
+ "GET",
60
+ "OPTIONS",
61
+ "POST",
62
+ "PUT",
63
+ "DELETE",
64
+ "TRACE",
65
+ "PATCH",
66
+ ],
67
+ )
68
+ adapter = HTTPAdapter(max_retries=retry_strategy)
69
+ session.mount("https://", adapter)
70
+ session.mount("http://", adapter)
71
+
72
+
73
+ class SessionSingleton:
74
+ """Singleton class to manage HTTP sessions for MambuPy.
75
+
76
+ This class ensures that only one requests.Session object is created and reused
77
+ across all requests to the Mambu API. This helps improve performance by reusing
78
+ TCP connections.
79
+
80
+ Example:
81
+ >>> session = SessionSingleton()
82
+ >>> session.get_session() # Returns a requests.Session object
83
+ >>> session2 = SessionSingleton()
84
+ >>> session2.get_session() # Returns the same requests.Session object
85
+ """
86
+
87
+ __instance = None
88
+ __session = None
89
+ _RETRIES = 5
90
+
91
+ def __new__(cls):
92
+ """Create a new instance of SessionSingleton if one doesn't exist.
93
+
94
+ Returns:
95
+ SessionSingleton: The singleton instance.
96
+ """
97
+ if cls.__instance is None:
98
+ cls.__instance = super(SessionSingleton, cls).__new__(cls)
99
+ return cls.__instance
100
+
101
+ def get_session(self):
102
+ """Get the requests.Session object.
103
+
104
+ If no session exists, create a new one. Otherwise, return the existing one.
105
+
106
+ Returns:
107
+ requests.Session: The session object to use for HTTP requests.
108
+ """
109
+ if self.__session is None:
110
+ self.__session = requests.Session()
111
+ _configure_retry_strategy(self.__session, self._RETRIES)
112
+ return self.__session
113
+
114
+
45
115
  class MambuConnectorREST(MambuConnector, MambuConnectorReader, MambuConnectorWriter):
46
116
  """A connector for Mambu REST API"""
47
117
 
@@ -52,10 +122,19 @@ class MambuConnectorREST(MambuConnector, MambuConnectorReader, MambuConnectorWri
52
122
  def __init__(self, user=apiuser, pwd=apipwd, url=apiurl, **kwargs):
53
123
  self._headers = {
54
124
  "Accept": "application/vnd.mambu.v2+json",
55
- "Authorization": "Basic {}".format(
56
- base64.b64encode(bytes("{}:{}".format(user, pwd), "utf-8")).decode()
57
- ),
58
125
  }
126
+ self.__set_authorization_header(user, pwd)
127
+ self.__set_url(url)
128
+ self._session = None
129
+ if activate_request_session_objects.lower() == "true":
130
+ self._session = SessionSingleton().get_session()
131
+
132
+ def __set_authorization_header(self, user, pwd):
133
+ self._headers["Authorization"] = "Basic {}".format(
134
+ base64.b64encode(bytes("{}:{}".format(user, pwd), "utf-8")).decode()
135
+ )
136
+
137
+ def __set_url(self, url):
59
138
  self._tenant = url
60
139
 
61
140
  def __request_headers(self, method, content_type):
@@ -102,26 +181,6 @@ class MambuConnectorREST(MambuConnector, MambuConnectorReader, MambuConnectorWri
102
181
  params = self.__request_params(params)
103
182
  data = self.__request_data(data)
104
183
 
105
- retry_strategy = Retry(
106
- total=self._RETRIES,
107
- status_forcelist=[429, 502, 503, 504],
108
- backoff_factor=1,
109
- allowed_methods=[
110
- "HEAD",
111
- "GET",
112
- "OPTIONS",
113
- "POST",
114
- "PUT",
115
- "DELETE",
116
- "TRACE",
117
- "PATCH",
118
- ],
119
- )
120
- adapter = HTTPAdapter(max_retries=retry_strategy)
121
- http = requests.Session()
122
- http.mount("https://", adapter)
123
- http.mount("http://", adapter)
124
-
125
184
  resp = ""
126
185
  try:
127
186
  logger.debug(
@@ -133,10 +192,15 @@ url %s, params %s, data %s, headers %s",
133
192
  data,
134
193
  [(k, v) for k, v in headers.items() if k != "Authorization"],
135
194
  )
136
- resp = http.request(method, url, params=params, data=data, headers=headers)
195
+ if self._session:
196
+ resp = self._session.request(method, url, params=params, data=data, headers=headers)
197
+ else:
198
+ http = requests.Session()
199
+ _configure_retry_strategy(http, self._RETRIES)
200
+ resp = http.request(method, url, params=params, data=data, headers=headers)
137
201
  resp.raise_for_status()
138
202
  except requests.exceptions.HTTPError as httperr:
139
- logger.error(
203
+ logger.warning(
140
204
  "%s on %s request: params %s, data %s, headers %s",
141
205
  str(httperr),
142
206
  method,
@@ -145,7 +209,7 @@ url %s, params %s, data %s, headers %s",
145
209
  [(k, v) for k, v in headers.items() if k != "Authorization"],
146
210
  )
147
211
  if hasattr(resp, "content"): # pragma: no cover
148
- logger.error("HTTPError, resp content: %s", resp.content)
212
+ logger.warning("HTTPError, resp content: %s", resp.content)
149
213
  try:
150
214
  content = json.loads(resp.content.decode())
151
215
  except ValueError:
@@ -489,36 +553,48 @@ url %s, params %s, data %s, headers %s",
489
553
 
490
554
  return self.__list_request("POST", url, params=params, data=data)
491
555
 
492
- def mambu_update(self, entid, prefix, attrs):
556
+ def mambu_update(self, entid, prefix, attrs, **kwargs):
493
557
  """updates a mambu entity
494
558
 
495
559
  Args:
496
560
  entid (str): the id or encoded key of the entity owning the document
497
561
  prefix (str): entity's URL prefix
498
562
  attrs (dict): entity to be updated, complying with Mambu's schemas
563
+ kwargs (dict): keyword arguments for this method.
564
+ May include a user, pwd and url to connect to Mambu.
499
565
 
500
566
  Returns:
501
567
  response content (str json {})
502
568
  """
569
+ if "url" in kwargs:
570
+ self.__set_url(kwargs["url"])
571
+ if "user" in kwargs and "pwd" in kwargs:
572
+ self.__set_authorization_header(kwargs["user"], kwargs["pwd"])
503
573
  url = "https://{}/api/{}/{}".format(self._tenant, prefix, entid)
504
574
 
505
575
  return self.__request("PUT", url, data=attrs)
506
576
 
507
- def mambu_create(self, prefix, attrs):
577
+ def mambu_create(self, prefix, attrs, **kwargs):
508
578
  """creates a mambu entity
509
579
 
510
580
  Args:
511
581
  prefix (str): entity's URL prefix
512
582
  attrs (dict): entity to be created, complying with Mambu's schemas
583
+ kwargs (dict): keyword arguments for this method.
584
+ May include a user, pwd and url to connect to Mambu.
513
585
 
514
586
  Returns:
515
587
  response content (str json {})
516
588
  """
589
+ if "url" in kwargs:
590
+ self.__set_url(kwargs["url"])
591
+ if "user" in kwargs and "pwd" in kwargs:
592
+ self.__set_authorization_header(kwargs["user"], kwargs["pwd"])
517
593
  url = "https://{}/api/{}".format(self._tenant, prefix)
518
594
 
519
595
  return self.__request("POST", url, data=attrs)
520
596
 
521
- def mambu_patch(self, entid, prefix, fields_ops=None):
597
+ def mambu_patch(self, entid, prefix, fields_ops=None, **kwargs):
522
598
  """patches certain parts of a mambu entity
523
599
 
524
600
  https://api.mambu.com/?python#tocspatchoperation
@@ -532,10 +608,16 @@ url %s, params %s, data %s, headers %s",
532
608
  OP (str): operation ("ADD", "REPLACE", "REMOVE")
533
609
  PATH (str): json pointer referencing the location in the target entity
534
610
  VALUE (obj, opc): the value of the field (not for REMOVE op)
611
+ kwargs (dict): keyword arguments for this method.
612
+ May include a user, pwd and url to connect to Mambu.
535
613
  """
536
614
  if not fields_ops:
537
615
  fields_ops = []
538
616
 
617
+ if "url" in kwargs:
618
+ self.__set_url(kwargs["url"])
619
+ if "user" in kwargs and "pwd" in kwargs:
620
+ self.__set_authorization_header(kwargs["user"], kwargs["pwd"])
539
621
  url = "https://{}/api/{}/{}".format(self._tenant, prefix, entid)
540
622
 
541
623
  # build data from fields_ops param
@@ -549,8 +631,16 @@ url %s, params %s, data %s, headers %s",
549
631
  if patch_data:
550
632
  return self.__request("PATCH", url, data=patch_data)
551
633
 
552
- def mambu_delete(self, entid, prefix):
553
- """deletes a mambu entity"""
634
+ def mambu_delete(self, entid, prefix, **kwargs):
635
+ """deletes a mambu entity
636
+
637
+ kwargs (dict): keyword arguments for this method.
638
+ May include a user, pwd and url to connect to Mambu.
639
+ """
640
+ if "url" in kwargs:
641
+ self.__set_url(kwargs["url"])
642
+ if "user" in kwargs and "pwd" in kwargs:
643
+ self.__set_authorization_header(kwargs["user"], kwargs["pwd"])
554
644
  url = "https://{}/api/{}/{}".format(self._tenant, prefix, entid)
555
645
 
556
646
  return self.__request("DELETE", url)
@@ -428,19 +428,22 @@ class MambuEntity(MambuStruct):
428
428
  class MambuEntityWritable(MambuStruct, MambuWritable):
429
429
  """A Mambu object with writing capabilities."""
430
430
 
431
- def update(self):
431
+ def update(self, **kwargs):
432
432
  """updates a mambu entity
433
433
 
434
434
  Uses the current values of the _attrs to send to Mambu.
435
435
  Pre-requires that CustomFields are updated previously.
436
436
  Post-requires that CustomFields are extracted again.
437
+
438
+ kwargs (dict): keyword arguments for this method.
439
+ May include a user, pwd and url to connect to Mambu.
437
440
  """
438
441
  self._updateVOs()
439
442
  self._updateCustomFields()
440
443
  self._serializeFields()
441
444
  try:
442
445
  self._connector.mambu_update(
443
- self.id, self._prefix, copy.deepcopy(self._attrs)
446
+ self.id, self._prefix, copy.deepcopy(self._attrs), **kwargs
444
447
  )
445
448
  # should I refresh _attrs? (either get request from Mambu or using the response)
446
449
  except MambuError:
@@ -450,19 +453,22 @@ class MambuEntityWritable(MambuStruct, MambuWritable):
450
453
  self._extractCustomFields()
451
454
  self._extractVOs()
452
455
 
453
- def create(self):
456
+ def create(self, **kwargs):
454
457
  """creates a mambu entity
455
458
 
456
459
  Uses the current values of the _attrs to send to Mambu.
457
460
  Pre-requires that CustomFields are updated previously.
458
461
  Post-requires that CustomFields are extracted again.
462
+
463
+ kwargs (dict): keyword arguments for this method.
464
+ May include a user, pwd and url to connect to Mambu.
459
465
  """
460
466
  self._updateVOs()
461
467
  self._updateCustomFields()
462
468
  self._serializeFields()
463
469
  try:
464
470
  self._resp = self._connector.mambu_create(
465
- self._prefix, copy.deepcopy(self._attrs)
471
+ self._prefix, copy.deepcopy(self._attrs), **kwargs
466
472
  )
467
473
  self._attrs.update(dict(json.loads(self._resp.decode())))
468
474
  self._tzattrs = dict(json.loads(self._resp.decode()))
@@ -516,7 +522,7 @@ class MambuEntityWritable(MambuStruct, MambuWritable):
516
522
  else:
517
523
  raise MambuPyError("Unrecognizable field {} for patching".format(field))
518
524
 
519
- def patch(self, fields=None, autodetect_remove=False):
525
+ def patch(self, fields=None, autodetect_remove=False, **kwargs):
520
526
  """patches a mambu entity
521
527
 
522
528
  Allows patching of parts of the entity up to Mambu.
@@ -583,7 +589,7 @@ class MambuEntityWritable(MambuStruct, MambuWritable):
583
589
  self._updateCustomFields()
584
590
  self._serializeFields()
585
591
  if fields_ops:
586
- self._connector.mambu_patch(self.id, self._prefix, fields_ops)
592
+ self._connector.mambu_patch(self.id, self._prefix, fields_ops, **kwargs)
587
593
  # should I refresh _attrs? (needs get request from Mambu)
588
594
  except MambuError:
589
595
  raise
@@ -599,7 +605,7 @@ class MambuEntityWritable(MambuStruct, MambuWritable):
599
605
  Implement on entities which require further cleaning.
600
606
  """
601
607
 
602
- def delete(self):
608
+ def delete(self, **kwargs):
603
609
  """deletes a mambu entity.
604
610
 
605
611
  Leaves the object in a supposedly state where you can create
@@ -610,7 +616,7 @@ class MambuEntityWritable(MambuStruct, MambuWritable):
610
616
  make sure we can run creation after deletion.
611
617
  """
612
618
  try:
613
- self._connector.mambu_delete(self.id, self._prefix)
619
+ self._connector.mambu_delete(self.id, self._prefix, **kwargs)
614
620
  except MambuError:
615
621
  raise
616
622
 
@@ -24,6 +24,7 @@ RC files must have the following format:
24
24
  apiuser=API_user
25
25
  apipwd=API_password
26
26
  apipagination=API_pagination_limit
27
+ activate_request_session_objects=API_persistent_session
27
28
  [DB]
28
29
  dbname=Database_name
29
30
  dbuser=Database_user
@@ -75,6 +76,10 @@ user on your Mambu instance
75
76
 
76
77
  The db* configs refer to Database configurations which hold a backup of
77
78
  your Mambu Database on some server.
79
+
80
+ The activate_request_session_objects config enables or disables HTTP persistent sessions
81
+ for API requests. When enabled, it will reuse the same TCP connection for
82
+ multiple requests, improving performance. Default is False.
78
83
  """
79
84
 
80
85
  default_configs = {
@@ -83,6 +88,7 @@ default_configs = {
83
88
  "apiuser": "mambu_api_user",
84
89
  "apipwd": "mambu_api_password",
85
90
  "apipagination": "50",
91
+ "activate_request_session_objects": "False",
86
92
  # Mambu DB configurations
87
93
  "dbname": "mambu_db",
88
94
  "dbuser": "mambu_db_user",
@@ -123,6 +129,7 @@ argparser.add_argument("--mambupy_apiurl")
123
129
  argparser.add_argument("--mambupy_apiuser")
124
130
  argparser.add_argument("--mambupy_apipwd")
125
131
  argparser.add_argument("--mambupy_apipagination")
132
+ argparser.add_argument("--mambupy_activate_request_session_objects")
126
133
  argparser.add_argument("--mambupy_dbname")
127
134
  argparser.add_argument("--mambupy_dbuser")
128
135
  argparser.add_argument("--mambupy_dbpwd")
@@ -184,6 +191,8 @@ apipwd = get_conf(config, "API", "apipwd")
184
191
  """Password to access Mambu API"""
185
192
  apipagination = get_conf(config, "API", "apipagination")
186
193
  """Pagination default limit for requests to Mambu API"""
194
+ activate_request_session_objects = get_conf(config, "API", "activate_request_session_objects")
195
+ """Whether to use persistent HTTP sessions for API requests"""
187
196
  dbname = get_conf(config, "DB", "dbname")
188
197
  """Name of the DB with a backup of Mambu's DB"""
189
198
  dbuser = get_conf(config, "DB", "dbuser")
@@ -28,7 +28,7 @@ from codecs import open as copen
28
28
 
29
29
  import yaml
30
30
 
31
- from .mambuconfig import apipagination, apipwd, apiurl, apiuser, loggingconf
31
+ from .mambuconfig import apipagination, apipwd, apiurl, apiuser, loggingconf, activate_request_session_objects
32
32
  from .mambugeturl import getmambuurl
33
33
 
34
34
  try:
@@ -258,7 +258,7 @@ def strip_consecutive_repeated_char(s, ch):
258
258
 
259
259
  if sys.version_info >= (3, 0):
260
260
  # python3
261
- from future.moves.urllib import parse as urlparse
261
+ from urllib import parse as urlparse
262
262
  else: # pragma: no cover
263
263
  # python2
264
264
  import urlparse
@@ -405,7 +405,7 @@ def _backup_db_timeout_mechanism(
405
405
  ):
406
406
  value_to_latest = True
407
407
  while not justbackup and retries and not bool_func():
408
- logger.info("waiting...")
408
+ logger.debug("waiting...")
409
409
  sleep(10)
410
410
  retries -= 1
411
411
  if retries < 0:
@@ -0,0 +1,49 @@
1
+ """MambuPy's REST package (SOON TO BE DEPRECATED).
2
+
3
+ Objects using `Mambu REST API
4
+ <https://developer.mambu.com/customer/en/portal/articles/1162276-rest-apis-overview/>`_
5
+
6
+ .. autosummary::
7
+ :toctree: _autosummary
8
+
9
+ MambuPy.rest.mambustruct
10
+ MambuPy.rest.mambuclient
11
+ MambuPy.rest.mambugroup
12
+ MambuPy.rest.mambuloan
13
+ MambuPy.rest.mamburepayment
14
+ MambuPy.rest.mambutransaction
15
+ MambuPy.rest.mambuproduct
16
+ MambuPy.rest.mambubranch
17
+ MambuPy.rest.mambucentre
18
+ MambuPy.rest.mambuactivity
19
+ MambuPy.rest.mambutask
20
+ MambuPy.rest.mambusaving
21
+ MambuPy.rest.mambusavingtransaction
22
+ MambuPy.rest.mambutransactionchannel
23
+ MambuPy.rest.mambuuser
24
+ MambuPy.rest.mamburoles
25
+
26
+ .. warning:: This package is soon to be deprecated. Use the :any:`MambuPy.api` package instead.
27
+
28
+ The REST API way is the currently most developed code on *MambuPy*.
29
+
30
+ Lives under the :any:`MambuPy.rest` package
31
+
32
+ It has a lot of objects which model some Mambu entity.
33
+
34
+ Every object inherits from the parent :any:`mambustruct.MambuStruct`
35
+ class. Start at the documentation there for more info on how it works.
36
+
37
+ .. todo:: Implement objects to make POST requests. The suggestion may be to use
38
+ MambuStruct, to default the __init__ to make a POST request (via the data
39
+ argument) and the attrs attribute to store the elements of the response that
40
+ Mambu gives when a successful POST is achieved.
41
+ .. todo:: Implement a lot of other Mambu entities available through GET requests on
42
+ Mambu.
43
+ .. todo:: Implement a lot of lacking GET filters on the currently available Mambu
44
+ objects, inside the urlfuncs on the mambuutil module.
45
+ .. todo:: A lot of TODO comments are inserted inside the pydocs of the code
46
+ itself. Please read them for suggestions on work need to be done.
47
+ """
48
+
49
+ from .. import mambuconfig, mambuutil
@@ -0,0 +1,87 @@
1
+ # coding: utf-8
2
+ """Mambu Activity objects.
3
+
4
+ .. autosummary::
5
+ :nosignatures:
6
+ :toctree: _autosummary
7
+
8
+ MambuActivity holds a mambu activity. Don't instantiate this class
9
+ directly. Look at MambuActivity pydoc for further info.
10
+
11
+ MambuActivities holds a list of activities.
12
+
13
+ Uses mambugeturl.getactivitiesurl as default urlfunc
14
+ """
15
+
16
+
17
+ from ..mambugeturl import getactivitiesurl
18
+ from .mambustruct import MambuStruct
19
+ from .mamburestutils import MambuStructIterator
20
+
21
+ mod_urlfunc = getactivitiesurl
22
+
23
+
24
+ class MambuActivity(MambuStruct):
25
+ """A loan Activity from Mambu.
26
+
27
+ Don't instantiate this class directly. It's mostly used by
28
+ MambuActivities to configure each of its elements as
29
+ MambuActivity objects. There's no suitable urlfunc to use to
30
+ retrieve just a specific transaction from a loan account. In fact,
31
+ you can look at the code of MambuActivities.convert_dict_to_attrs(),
32
+ it uses urlfunc and entid = None , so no connection to Mambu will be
33
+ made, never, for any particular MambuActivity object.
34
+ """
35
+
36
+ def __init__(self, urlfunc=mod_urlfunc, entid="", *args, **kwargs):
37
+ """Tasks done here:
38
+
39
+ Just initializes the MambuStruct.
40
+ """
41
+ MambuStruct.__init__(self, urlfunc, entid, *args, **kwargs)
42
+
43
+ def __repr__(self):
44
+ """Instead of the default id given by the parent class, shows
45
+ the transactionid of the transaction.
46
+ """
47
+ try:
48
+ return self.__class__.__name__ + " - activityid: %s" % self["activity"]
49
+ except KeyError:
50
+ return self.__class__.__name__ + " - activityid: %s" % self["activity"]
51
+
52
+
53
+ class MambuActivities(MambuStruct):
54
+ """A list of loan Activities from Mambu."""
55
+
56
+ def __init__(self, urlfunc=mod_urlfunc, entid="", *args, **kwargs):
57
+ MambuStruct.__init__(self, urlfunc, entid, *args, **kwargs)
58
+
59
+ def __iter__(self):
60
+ return MambuStructIterator(self.attrs)
61
+
62
+ def convert_dict_to_attrs(self, *args, **kwargs):
63
+ """The trick for iterable Mambu Objects comes here:
64
+
65
+ You iterate over each element of the responded List from Mambu,
66
+ and create a Mambu Activity object for each one, initializing
67
+ them one at a time, and changing the attrs attribute (which just
68
+ holds a list of plain dictionaries) with a MambuActivity just
69
+ created.
70
+
71
+ """
72
+ for n, a in enumerate(self.attrs):
73
+ # ok ok, I'm modifying elements of a list while iterating it. BAD PRACTICE!
74
+ try:
75
+ params = self.params
76
+ except AttributeError:
77
+ params = {}
78
+ kwargs.update(params)
79
+ try:
80
+ self.mambuactivityclass
81
+ except AttributeError:
82
+ self.mambuactivityclass = MambuActivity
83
+
84
+ activity = self.mambuactivityclass(urlfunc=None, entid=None, *args, **kwargs)
85
+ activity.init(a, *args, **kwargs)
86
+ activity._MambuStruct__urlfunc = getactivitiesurl
87
+ self.attrs[n] = activity