MambuPy 2.1.0__tar.gz → 2.2.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.
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/__init__.py +2 -4
- {mambupy-2.1.0/mambupy → mambupy-2.2.1/MambuPy}/api/connector/rest.py +81 -23
- {mambupy-2.1.0/mambupy → mambupy-2.2.1/MambuPy}/mambuconfig.py +12 -13
- {mambupy-2.1.0/mambupy → mambupy-2.2.1/MambuPy}/mambuutil.py +16 -62
- {mambupy-2.1.0/mambupy → mambupy-2.2.1/MambuPy}/orm/schema_groups.py +3 -4
- {mambupy-2.1.0/mambupy → mambupy-2.2.1/MambuPy}/orm/schema_orm.py +0 -2
- mambupy-2.2.1/MambuPy/rest/__init__.py +31 -0
- mambupy-2.2.1/MambuPy/rest/mambuactivity.py +744 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy.egg-info/PKG-INFO +5 -4
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy.egg-info/SOURCES.txt +0 -34
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy.egg-info/requires.txt +1 -1
- {mambupy-2.1.0 → mambupy-2.2.1}/PKG-INFO +5 -4
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/__init__.py +2 -4
- {mambupy-2.1.0/MambuPy → mambupy-2.2.1/mambupy}/api/connector/rest.py +81 -23
- {mambupy-2.1.0/MambuPy → mambupy-2.2.1/mambupy}/mambuconfig.py +12 -13
- {mambupy-2.1.0/MambuPy → mambupy-2.2.1/mambupy}/mambuutil.py +16 -62
- {mambupy-2.1.0/MambuPy → mambupy-2.2.1/mambupy}/orm/schema_groups.py +3 -4
- {mambupy-2.1.0/MambuPy → mambupy-2.2.1/mambupy}/orm/schema_orm.py +0 -2
- mambupy-2.2.1/mambupy/rest/__init__.py +31 -0
- mambupy-2.2.1/mambupy/rest/mambuactivity.py +744 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/pyproject.toml +8 -3
- mambupy-2.1.0/MambuPy/rest/__init__.py +0 -49
- mambupy-2.1.0/MambuPy/rest/mambuactivity.py +0 -87
- mambupy-2.1.0/MambuPy/rest/mambubranch.py +0 -122
- mambupy-2.1.0/MambuPy/rest/mambucentre.py +0 -104
- mambupy-2.1.0/MambuPy/rest/mambuclient.py +0 -317
- mambupy-2.1.0/MambuPy/rest/mambugroup.py +0 -372
- mambupy-2.1.0/MambuPy/rest/mambuloan.py +0 -687
- mambupy-2.1.0/MambuPy/rest/mambuproduct.py +0 -180
- mambupy-2.1.0/MambuPy/rest/mamburepayment.py +0 -99
- mambupy-2.1.0/MambuPy/rest/mamburestutils.py +0 -119
- mambupy-2.1.0/MambuPy/rest/mamburoles.py +0 -98
- mambupy-2.1.0/MambuPy/rest/mambusaving.py +0 -114
- mambupy-2.1.0/MambuPy/rest/mambusavingfundingrepayment.py +0 -94
- mambupy-2.1.0/MambuPy/rest/mambusavingtransaction.py +0 -163
- mambupy-2.1.0/MambuPy/rest/mambustruct.py +0 -1066
- mambupy-2.1.0/MambuPy/rest/mambutask.py +0 -163
- mambupy-2.1.0/MambuPy/rest/mambutransaction.py +0 -103
- mambupy-2.1.0/MambuPy/rest/mambutransactionchannel.py +0 -101
- mambupy-2.1.0/MambuPy/rest/mambuuser.py +0 -229
- mambupy-2.1.0/mambupy/rest/__init__.py +0 -49
- mambupy-2.1.0/mambupy/rest/mambuactivity.py +0 -87
- mambupy-2.1.0/mambupy/rest/mambubranch.py +0 -122
- mambupy-2.1.0/mambupy/rest/mambucentre.py +0 -104
- mambupy-2.1.0/mambupy/rest/mambuclient.py +0 -317
- mambupy-2.1.0/mambupy/rest/mambugroup.py +0 -372
- mambupy-2.1.0/mambupy/rest/mambuloan.py +0 -687
- mambupy-2.1.0/mambupy/rest/mambuproduct.py +0 -180
- mambupy-2.1.0/mambupy/rest/mamburepayment.py +0 -99
- mambupy-2.1.0/mambupy/rest/mamburestutils.py +0 -119
- mambupy-2.1.0/mambupy/rest/mamburoles.py +0 -98
- mambupy-2.1.0/mambupy/rest/mambusaving.py +0 -114
- mambupy-2.1.0/mambupy/rest/mambusavingfundingrepayment.py +0 -94
- mambupy-2.1.0/mambupy/rest/mambusavingtransaction.py +0 -163
- mambupy-2.1.0/mambupy/rest/mambustruct.py +0 -1066
- mambupy-2.1.0/mambupy/rest/mambutask.py +0 -163
- mambupy-2.1.0/mambupy/rest/mambutransaction.py +0 -103
- mambupy-2.1.0/mambupy/rest/mambutransactionchannel.py +0 -101
- mambupy-2.1.0/mambupy/rest/mambuuser.py +0 -229
- {mambupy-2.1.0 → mambupy-2.2.1}/LICENSE +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/__init__.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/classes.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/connector/__init__.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/connector/mambuconnector.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/entities.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/interfaces.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/mambubranch.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/mambucentre.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/mambuclient.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/mambucustomfield.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/mambugroup.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/mambuloan.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/mambuproduct.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/mamburole.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/mambustruct.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/mambutask.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/mambutransaction.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/mambuuser.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/api/vos.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/mambugeturl.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/orm/__init__.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/orm/schema_activities.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/orm/schema_addresses.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/orm/schema_branches.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/orm/schema_centres.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/orm/schema_clients.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/orm/schema_customfields.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/orm/schema_dummies.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/orm/schema_loans.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/orm/schema_mambu.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/orm/schema_tasks.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/orm/schema_users.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/utils/__init__.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy/utils/userdeactivate.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy.egg-info/dependency_links.txt +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/MambuPy.egg-info/top_level.txt +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/README.md +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/__init__.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/classes.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/connector/__init__.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/connector/mambuconnector.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/entities.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/interfaces.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/mambubranch.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/mambucentre.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/mambuclient.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/mambucustomfield.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/mambugroup.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/mambuloan.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/mambuproduct.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/mamburole.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/mambustruct.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/mambutask.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/mambutransaction.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/mambuuser.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/api/vos.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/mambugeturl.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/orm/__init__.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/orm/schema_activities.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/orm/schema_addresses.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/orm/schema_branches.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/orm/schema_centres.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/orm/schema_clients.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/orm/schema_customfields.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/orm/schema_dummies.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/orm/schema_loans.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/orm/schema_mambu.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/orm/schema_tasks.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/orm/schema_users.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/utils/__init__.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/mambupy/utils/userdeactivate.py +0 -0
- {mambupy-2.1.0 → mambupy-2.2.1}/setup.cfg +0 -0
|
@@ -8,15 +8,13 @@
|
|
|
8
8
|
MambuPy.api
|
|
9
9
|
MambuPy.api.connector
|
|
10
10
|
MambuPy.orm
|
|
11
|
-
MambuPy.rest
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
Currently, there are two different ways to access Mambu objects:
|
|
15
14
|
|
|
16
15
|
1) Objects using `Mambu REST API
|
|
17
16
|
<https://developer.mambu.com/customer/en/portal/articles/1162276-rest-apis-overview/>`_
|
|
18
|
-
, they live at the :any:`MambuPy.api` package
|
|
19
|
-
V1-compatible code lives at :any:`MambuPy.rest`
|
|
17
|
+
, they live at the :any:`MambuPy.api` package
|
|
20
18
|
|
|
21
19
|
2) An ORM using a `DB backup retrieved from Mambu
|
|
22
20
|
<https://support.mambu.com/docs/mambu-data-dictionary>`_
|
|
@@ -39,7 +37,7 @@ import sys
|
|
|
39
37
|
from importlib.abc import MetaPathFinder
|
|
40
38
|
from importlib.util import spec_from_file_location
|
|
41
39
|
|
|
42
|
-
__version__ = "2.1
|
|
40
|
+
__version__ = "2.2.1"
|
|
43
41
|
"""The version of this module."""
|
|
44
42
|
|
|
45
43
|
|
|
@@ -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
|
|
|
@@ -55,6 +125,9 @@ class MambuConnectorREST(MambuConnector, MambuConnectorReader, MambuConnectorWri
|
|
|
55
125
|
}
|
|
56
126
|
self.__set_authorization_header(user, pwd)
|
|
57
127
|
self.__set_url(url)
|
|
128
|
+
self._session = None
|
|
129
|
+
if activate_request_session_objects.lower() == "true":
|
|
130
|
+
self._session = SessionSingleton().get_session()
|
|
58
131
|
|
|
59
132
|
def __set_authorization_header(self, user, pwd):
|
|
60
133
|
self._headers["Authorization"] = "Basic {}".format(
|
|
@@ -108,26 +181,6 @@ class MambuConnectorREST(MambuConnector, MambuConnectorReader, MambuConnectorWri
|
|
|
108
181
|
params = self.__request_params(params)
|
|
109
182
|
data = self.__request_data(data)
|
|
110
183
|
|
|
111
|
-
retry_strategy = Retry(
|
|
112
|
-
total=self._RETRIES,
|
|
113
|
-
status_forcelist=[429, 500, 502, 503, 504],
|
|
114
|
-
backoff_factor=1,
|
|
115
|
-
allowed_methods=[
|
|
116
|
-
"HEAD",
|
|
117
|
-
"GET",
|
|
118
|
-
"OPTIONS",
|
|
119
|
-
"POST",
|
|
120
|
-
"PUT",
|
|
121
|
-
"DELETE",
|
|
122
|
-
"TRACE",
|
|
123
|
-
"PATCH",
|
|
124
|
-
],
|
|
125
|
-
)
|
|
126
|
-
adapter = HTTPAdapter(max_retries=retry_strategy)
|
|
127
|
-
http = requests.Session()
|
|
128
|
-
http.mount("https://", adapter)
|
|
129
|
-
http.mount("http://", adapter)
|
|
130
|
-
|
|
131
184
|
resp = ""
|
|
132
185
|
try:
|
|
133
186
|
logger.debug(
|
|
@@ -139,10 +192,15 @@ url %s, params %s, data %s, headers %s",
|
|
|
139
192
|
data,
|
|
140
193
|
[(k, v) for k, v in headers.items() if k != "Authorization"],
|
|
141
194
|
)
|
|
142
|
-
|
|
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)
|
|
143
201
|
resp.raise_for_status()
|
|
144
202
|
except requests.exceptions.HTTPError as httperr:
|
|
145
|
-
logger.
|
|
203
|
+
logger.warning(
|
|
146
204
|
"%s on %s request: params %s, data %s, headers %s",
|
|
147
205
|
str(httperr),
|
|
148
206
|
method,
|
|
@@ -151,7 +209,7 @@ url %s, params %s, data %s, headers %s",
|
|
|
151
209
|
[(k, v) for k, v in headers.items() if k != "Authorization"],
|
|
152
210
|
)
|
|
153
211
|
if hasattr(resp, "content"): # pragma: no cover
|
|
154
|
-
logger.
|
|
212
|
+
logger.warning("HTTPError, resp content: %s", resp.content)
|
|
155
213
|
try:
|
|
156
214
|
content = json.loads(resp.content.decode())
|
|
157
215
|
except ValueError:
|
|
@@ -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",
|
|
@@ -99,20 +105,10 @@ You may edit this to your own liking. But beware of pricking eyes!
|
|
|
99
105
|
"""
|
|
100
106
|
|
|
101
107
|
import os
|
|
108
|
+
import configparser
|
|
109
|
+
from configparser import NoSectionError
|
|
102
110
|
|
|
103
|
-
|
|
104
|
-
import sys
|
|
105
|
-
|
|
106
|
-
if sys.version_info.major < 3:
|
|
107
|
-
import ConfigParser
|
|
108
|
-
from ConfigParser import NoSectionError
|
|
109
|
-
|
|
110
|
-
config = ConfigParser.ConfigParser(defaults=default_configs)
|
|
111
|
-
else:
|
|
112
|
-
import configparser
|
|
113
|
-
from configparser import NoSectionError
|
|
114
|
-
|
|
115
|
-
config = configparser.ConfigParser(defaults=default_configs)
|
|
111
|
+
config = configparser.ConfigParser(defaults=default_configs)
|
|
116
112
|
|
|
117
113
|
# argparse for command line arguments overriding
|
|
118
114
|
import argparse
|
|
@@ -123,6 +119,7 @@ argparser.add_argument("--mambupy_apiurl")
|
|
|
123
119
|
argparser.add_argument("--mambupy_apiuser")
|
|
124
120
|
argparser.add_argument("--mambupy_apipwd")
|
|
125
121
|
argparser.add_argument("--mambupy_apipagination")
|
|
122
|
+
argparser.add_argument("--mambupy_activate_request_session_objects")
|
|
126
123
|
argparser.add_argument("--mambupy_dbname")
|
|
127
124
|
argparser.add_argument("--mambupy_dbuser")
|
|
128
125
|
argparser.add_argument("--mambupy_dbpwd")
|
|
@@ -184,6 +181,8 @@ apipwd = get_conf(config, "API", "apipwd")
|
|
|
184
181
|
"""Password to access Mambu API"""
|
|
185
182
|
apipagination = get_conf(config, "API", "apipagination")
|
|
186
183
|
"""Pagination default limit for requests to Mambu API"""
|
|
184
|
+
activate_request_session_objects = get_conf(config, "API", "activate_request_session_objects")
|
|
185
|
+
"""Whether to use persistent HTTP sessions for API requests"""
|
|
187
186
|
dbname = get_conf(config, "DB", "dbname")
|
|
188
187
|
"""Name of the DB with a backup of Mambu's DB"""
|
|
189
188
|
dbuser = get_conf(config, "DB", "dbuser")
|
|
@@ -28,16 +28,9 @@ 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
|
-
try:
|
|
35
|
-
# python2
|
|
36
|
-
unicode
|
|
37
|
-
except NameError:
|
|
38
|
-
# python3
|
|
39
|
-
unicode = str
|
|
40
|
-
|
|
41
34
|
import json
|
|
42
35
|
import sys
|
|
43
36
|
from datetime import datetime, timezone
|
|
@@ -186,21 +179,23 @@ def date_format(field, formato=None, as_utc=False):
|
|
|
186
179
|
|
|
187
180
|
if not formato:
|
|
188
181
|
formato = "%Y-%m-%dT%H:%M:%S"
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
182
|
+
|
|
183
|
+
field_with_tz = datetime.fromisoformat(field)
|
|
184
|
+
|
|
185
|
+
if as_utc and field_with_tz.tzinfo is not None:
|
|
186
|
+
# Convertir a UTC mientras aún tiene tzinfo
|
|
187
|
+
field_as_dt = field_with_tz.astimezone(timezone.utc)
|
|
188
|
+
field_as_dt = datetime.strptime(
|
|
189
|
+
field_as_dt.strftime(formato),
|
|
192
190
|
formato,
|
|
193
191
|
)
|
|
194
192
|
else:
|
|
195
193
|
field_as_dt = datetime.strptime(
|
|
196
|
-
|
|
194
|
+
field_with_tz.strftime(formato),
|
|
197
195
|
formato,
|
|
198
196
|
)
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
timezone.utc
|
|
202
|
-
).replace(tzinfo=None)
|
|
203
|
-
return field_as_dt
|
|
197
|
+
|
|
198
|
+
return field_as_dt
|
|
204
199
|
|
|
205
200
|
|
|
206
201
|
def strip_tags(html):
|
|
@@ -221,10 +216,7 @@ def strip_tags(html):
|
|
|
221
216
|
"""
|
|
222
217
|
|
|
223
218
|
def __init__(self):
|
|
224
|
-
|
|
225
|
-
super().__init__() # required for python3
|
|
226
|
-
except TypeError: # pragma: no cover
|
|
227
|
-
pass # with python2 raises TypeError
|
|
219
|
+
super().__init__()
|
|
228
220
|
self.reset()
|
|
229
221
|
self.fed = []
|
|
230
222
|
|
|
@@ -256,12 +248,7 @@ def strip_consecutive_repeated_char(s, ch):
|
|
|
256
248
|
return sdest
|
|
257
249
|
|
|
258
250
|
|
|
259
|
-
|
|
260
|
-
# python3
|
|
261
|
-
from future.moves.urllib import parse as urlparse
|
|
262
|
-
else: # pragma: no cover
|
|
263
|
-
# python2
|
|
264
|
-
import urlparse
|
|
251
|
+
from urllib import parse as urlparse
|
|
265
252
|
|
|
266
253
|
|
|
267
254
|
def iri_to_uri(iri):
|
|
@@ -277,35 +264,9 @@ def iri_to_uri(iri):
|
|
|
277
264
|
unicode chars there. Using this I solved the problem.
|
|
278
265
|
"""
|
|
279
266
|
|
|
280
|
-
def url_encode_non_ascii(b):
|
|
281
|
-
"""Encode Non ASCII chars to URL-friendly chars.
|
|
282
|
-
|
|
283
|
-
Sometimes unicode gets in the way. A shame, I know. And perhaps the
|
|
284
|
-
biggest shame is not me correctly handling it.
|
|
285
|
-
"""
|
|
286
|
-
import re
|
|
287
|
-
|
|
288
|
-
return re.sub("[\x80-\xFF]", lambda c: "%%%02x" % ord(c.group(0)), b)
|
|
289
|
-
|
|
290
267
|
parts = urlparse.urlparse(iri)
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
partes = []
|
|
294
|
-
for parti, part in enumerate(parts):
|
|
295
|
-
try:
|
|
296
|
-
if parti != 1:
|
|
297
|
-
partes.append(url_encode_non_ascii(part.encode("utf-8")))
|
|
298
|
-
else:
|
|
299
|
-
partes.append(part.encode("idna"))
|
|
300
|
-
except UnicodeDecodeError:
|
|
301
|
-
partes.append(url_encode_non_ascii(part.decode("latin")))
|
|
302
|
-
except Exception:
|
|
303
|
-
raise Exception
|
|
304
|
-
return urlparse.urlunparse(partes)
|
|
305
|
-
else:
|
|
306
|
-
# python3
|
|
307
|
-
uri = [part.decode("utf8") for parti, part in enumerate(parts.encode("utf8"))]
|
|
308
|
-
return urlparse.urlunparse(uri)
|
|
268
|
+
uri = [part.decode("utf8") for parti, part in enumerate(parts.encode("utf8"))]
|
|
269
|
+
return urlparse.urlunparse(uri)
|
|
309
270
|
|
|
310
271
|
|
|
311
272
|
def encoded_dict(in_dict):
|
|
@@ -315,13 +276,6 @@ def encoded_dict(in_dict):
|
|
|
315
276
|
"""
|
|
316
277
|
out_dict = {}
|
|
317
278
|
for k, v in in_dict.items():
|
|
318
|
-
if isinstance(v, unicode):
|
|
319
|
-
if sys.version_info < (3, 0): # pragma: no cover
|
|
320
|
-
v = v.encode("utf8")
|
|
321
|
-
elif isinstance(v, str):
|
|
322
|
-
# Must be encoded in UTF-8
|
|
323
|
-
if sys.version_info < (3, 0): # pragma: no cover
|
|
324
|
-
v.decode("utf8")
|
|
325
279
|
out_dict[k] = v
|
|
326
280
|
return out_dict
|
|
327
281
|
|
|
@@ -15,10 +15,9 @@ from .schema_users import User
|
|
|
15
15
|
|
|
16
16
|
# technical debt, cannot import name schema_clients
|
|
17
17
|
try:
|
|
18
|
-
from . import
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
import schema_clients # python 2
|
|
18
|
+
from . import schema_clients
|
|
19
|
+
except Exception:
|
|
20
|
+
import schema_clients
|
|
22
21
|
|
|
23
22
|
from sqlalchemy import (Column, DateTime, ForeignKey, Integer, Numeric, String,
|
|
24
23
|
Text)
|
|
@@ -23,8 +23,6 @@ every schema_*.py you need.
|
|
|
23
23
|
This last requirement also applies for the Base, or for the engine and
|
|
24
24
|
the sessionmaker for that matter.
|
|
25
25
|
"""
|
|
26
|
-
from __future__ import absolute_import
|
|
27
|
-
|
|
28
26
|
from sqlalchemy.ext.declarative import declarative_base
|
|
29
27
|
from sqlalchemy.orm import sessionmaker, scoped_session
|
|
30
28
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
"""MambuPy REST module - DEPRECATED.
|
|
3
|
+
|
|
4
|
+
.. warning::
|
|
5
|
+
|
|
6
|
+
DEPRECATED: This module uses Mambu API v1 which is no longer supported.
|
|
7
|
+
This code is maintained only for backwards compatibility with legacy systems.
|
|
8
|
+
It will be removed in a future version of MambuPy.
|
|
9
|
+
|
|
10
|
+
Only mambuactivity is available in this legacy module.
|
|
11
|
+
"""
|
|
12
|
+
import warnings
|
|
13
|
+
|
|
14
|
+
warnings.warn(
|
|
15
|
+
"MambuPy.rest module is deprecated and will be removed in a future version. "
|
|
16
|
+
"Mambu API v1 is no longer supported by Mambu.",
|
|
17
|
+
DeprecationWarning,
|
|
18
|
+
stacklevel=2,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
from .mambuactivity import (
|
|
22
|
+
MambuActivity,
|
|
23
|
+
MambuActivities,
|
|
24
|
+
getactivitiesurl,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
__all__ = [
|
|
28
|
+
"MambuActivity",
|
|
29
|
+
"MambuActivities",
|
|
30
|
+
"getactivitiesurl",
|
|
31
|
+
]
|