mangopay4-python-sdk 3.52.0__py2.py3-none-any.whl
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.
- mangopay/__init__.py +27 -0
- mangopay/api.py +381 -0
- mangopay/auth.py +130 -0
- mangopay/base.py +289 -0
- mangopay/compat.py +16 -0
- mangopay/constants.py +466 -0
- mangopay/exceptions.py +26 -0
- mangopay/fields.py +1345 -0
- mangopay/page.py +17 -0
- mangopay/query.py +280 -0
- mangopay/ratelimit.py +5 -0
- mangopay/resources.py +3219 -0
- mangopay/signals.py +14 -0
- mangopay/utils.py +1582 -0
- mangopay4_python_sdk-3.52.0.dist-info/METADATA +53 -0
- mangopay4_python_sdk-3.52.0.dist-info/RECORD +20 -0
- mangopay4_python_sdk-3.52.0.dist-info/WHEEL +6 -0
- mangopay4_python_sdk-3.52.0.dist-info/entry_points.txt +2 -0
- mangopay4_python_sdk-3.52.0.dist-info/licenses/LICENSE +22 -0
- mangopay4_python_sdk-3.52.0.dist-info/top_level.txt +1 -0
mangopay/base.py
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
from copy import deepcopy
|
|
2
|
+
|
|
3
|
+
import six
|
|
4
|
+
|
|
5
|
+
from . import get_default_handler
|
|
6
|
+
from .fields import PrimaryKeyField, FieldDescriptor, Field, ForeignRelatedObject
|
|
7
|
+
from .query import UpdateQuery, InsertQuery, SelectQuery, DeleteQuery
|
|
8
|
+
from .signals import pre_save, post_save
|
|
9
|
+
from .utils import force_text, force_str
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class DoesNotExist(Exception):
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class BaseModelOptions(object):
|
|
17
|
+
def __init__(self, model_class, options=None):
|
|
18
|
+
self.rel_fields = {}
|
|
19
|
+
self.fields = {}
|
|
20
|
+
self.api_names = {}
|
|
21
|
+
self.options = options or {}
|
|
22
|
+
self.reverse_relations = {}
|
|
23
|
+
self.defaults = {}
|
|
24
|
+
|
|
25
|
+
for k, v in self.options.items():
|
|
26
|
+
setattr(self, k, v)
|
|
27
|
+
|
|
28
|
+
self.model_class = model_class
|
|
29
|
+
|
|
30
|
+
def get_sorted_fields(self):
|
|
31
|
+
return sorted(self.fields.items(), key=lambda k, v: (k == self.pk_name and 1 or 2, v._order))
|
|
32
|
+
|
|
33
|
+
def get_field_names(self):
|
|
34
|
+
return [f[0] for f in self.get_sorted_fields()]
|
|
35
|
+
|
|
36
|
+
def get_fields(self):
|
|
37
|
+
return [f[1] for f in self.get_sorted_fields()]
|
|
38
|
+
|
|
39
|
+
def get_field_by_name(self, name):
|
|
40
|
+
if name in self.fields:
|
|
41
|
+
return self.fields[name]
|
|
42
|
+
raise AttributeError('Field named %s not found' % name)
|
|
43
|
+
|
|
44
|
+
def __contains__(self, k):
|
|
45
|
+
return k in self.options
|
|
46
|
+
|
|
47
|
+
def __setitem__(self, k, value):
|
|
48
|
+
self.options[k] = value
|
|
49
|
+
|
|
50
|
+
def __delitem__(self, k):
|
|
51
|
+
if k not in self.options:
|
|
52
|
+
raise KeyError('%s does not exists' % k)
|
|
53
|
+
|
|
54
|
+
del self.options[k]
|
|
55
|
+
|
|
56
|
+
def prepared(self):
|
|
57
|
+
for field in self.fields.values():
|
|
58
|
+
if field.default is None:
|
|
59
|
+
continue
|
|
60
|
+
|
|
61
|
+
self.defaults[field] = field.default
|
|
62
|
+
|
|
63
|
+
def get_default_dict(self):
|
|
64
|
+
dd = {}
|
|
65
|
+
for field, default in self.defaults.items():
|
|
66
|
+
if callable(default):
|
|
67
|
+
dd[field.name] = default()
|
|
68
|
+
else:
|
|
69
|
+
dd[field.name] = default
|
|
70
|
+
return dd
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class ApiObjectBase(type):
|
|
74
|
+
inheritable_options = ['verbose_name', 'verbose_name_plural']
|
|
75
|
+
|
|
76
|
+
def __new__(cls, name, bases, attrs):
|
|
77
|
+
super_new = super(ApiObjectBase, cls).__new__
|
|
78
|
+
parents = [b for b in bases if isinstance(b, ApiObjectBase)]
|
|
79
|
+
|
|
80
|
+
if not parents:
|
|
81
|
+
# If this isn't a subclass of Model, don't do anything special.
|
|
82
|
+
return super_new(cls, name, bases, attrs)
|
|
83
|
+
|
|
84
|
+
module = attrs.pop('__module__')
|
|
85
|
+
new_class = super_new(cls, name, bases, {'__module__': module})
|
|
86
|
+
|
|
87
|
+
meta_options = {}
|
|
88
|
+
meta = attrs.pop('Meta', None)
|
|
89
|
+
if meta:
|
|
90
|
+
meta_options.update((k, v) for k, v in meta.__dict__.items() if not k.startswith('_'))
|
|
91
|
+
|
|
92
|
+
if 'urls' not in meta_options:
|
|
93
|
+
meta_options['urls'] = {}
|
|
94
|
+
|
|
95
|
+
orig_primary_key = None
|
|
96
|
+
|
|
97
|
+
for b in bases:
|
|
98
|
+
if not hasattr(b, '_meta'):
|
|
99
|
+
continue
|
|
100
|
+
|
|
101
|
+
base_meta = getattr(b, '_meta')
|
|
102
|
+
for (k, v) in base_meta.__dict__.items():
|
|
103
|
+
if k in cls.inheritable_options and k not in meta_options:
|
|
104
|
+
meta_options[k] = v
|
|
105
|
+
|
|
106
|
+
for (k, attr) in b.__dict__.items():
|
|
107
|
+
if isinstance(attr, ForeignRelatedObject) and isinstance(getattr(attr, 'old_field'), Field):
|
|
108
|
+
attrs[k] = deepcopy(getattr(attr, 'old_field'))
|
|
109
|
+
if not isinstance(attr, FieldDescriptor) or attr in attrs:
|
|
110
|
+
continue
|
|
111
|
+
|
|
112
|
+
attrs[k] = deepcopy(attr.field)
|
|
113
|
+
|
|
114
|
+
if isinstance(attr.field, PrimaryKeyField) and not orig_primary_key:
|
|
115
|
+
orig_primary_key = deepcopy(attr.field)
|
|
116
|
+
|
|
117
|
+
cls = super(ApiObjectBase, cls).__new__(cls, name, bases, attrs)
|
|
118
|
+
|
|
119
|
+
_meta = BaseModelOptions(cls, meta_options)
|
|
120
|
+
cls._meta = _meta
|
|
121
|
+
cls._data = None
|
|
122
|
+
|
|
123
|
+
for name, attr in list(cls.__dict__.items()):
|
|
124
|
+
if not isinstance(attr, Field):
|
|
125
|
+
continue
|
|
126
|
+
|
|
127
|
+
attr.add_to_class(cls, name)
|
|
128
|
+
_meta.fields[attr.name] = attr
|
|
129
|
+
_meta.api_names[attr.api_name] = attr.name
|
|
130
|
+
|
|
131
|
+
if isinstance(attr, PrimaryKeyField):
|
|
132
|
+
orig_primary_key = attr
|
|
133
|
+
|
|
134
|
+
if orig_primary_key is not None:
|
|
135
|
+
_meta.pk_name = orig_primary_key.name
|
|
136
|
+
|
|
137
|
+
_meta.model_name = new_class.__name__
|
|
138
|
+
|
|
139
|
+
exception_class = type('%sDoesNotExist' % _meta.model_name, (DoesNotExist,), {})
|
|
140
|
+
|
|
141
|
+
cls.DoesNotExist = exception_class
|
|
142
|
+
cls._meta.prepared()
|
|
143
|
+
|
|
144
|
+
return cls
|
|
145
|
+
|
|
146
|
+
@six.add_metaclass(ApiObjectBase)
|
|
147
|
+
class BaseApiModelMethods(object):
|
|
148
|
+
def __init__(self, *args, **kwargs):
|
|
149
|
+
self._data = self._meta.get_default_dict()
|
|
150
|
+
self._handler = kwargs.pop('handler', None)
|
|
151
|
+
|
|
152
|
+
for k, v in kwargs.items():
|
|
153
|
+
setattr(self, k, v)
|
|
154
|
+
|
|
155
|
+
@property
|
|
156
|
+
def handler(self):
|
|
157
|
+
return self._handler or get_default_handler()
|
|
158
|
+
|
|
159
|
+
def __repr__(self):
|
|
160
|
+
try:
|
|
161
|
+
u = six.text_type(self)
|
|
162
|
+
except (UnicodeEncodeError, UnicodeDecodeError):
|
|
163
|
+
u = '[Bad Unicode data]'
|
|
164
|
+
return force_str('<%s: %s>' % (self.__class__.__name__, u))
|
|
165
|
+
|
|
166
|
+
def __str__(self):
|
|
167
|
+
if six.PY2 and hasattr(self, '__unicode__'):
|
|
168
|
+
return force_text(self).encode('utf-8')
|
|
169
|
+
|
|
170
|
+
return '%s object' % self.__class__.__name__
|
|
171
|
+
|
|
172
|
+
def __eq__(self, other):
|
|
173
|
+
return (other.__class__ == self.__class__ and
|
|
174
|
+
self.get_pk() and
|
|
175
|
+
other.get_pk() == self.get_pk())
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class BaseApiModel(BaseApiModelMethods):
|
|
179
|
+
|
|
180
|
+
def __getattr__(self, name):
|
|
181
|
+
return object.__getattribute__(self, self._meta.api_names.get(name, name))
|
|
182
|
+
|
|
183
|
+
def __setattr__(self, name, value):
|
|
184
|
+
super(BaseApiModel, self).__setattr__(self._meta.api_names.get(name, name), value)
|
|
185
|
+
|
|
186
|
+
def fixed_kwargs(self):
|
|
187
|
+
return {}
|
|
188
|
+
|
|
189
|
+
def save(self, handler=None, cls=None, idempotency_key=None):
|
|
190
|
+
self._handler = handler or self.handler
|
|
191
|
+
|
|
192
|
+
field_dict = dict(self._data)
|
|
193
|
+
field_dict.update(self.get_field_dict())
|
|
194
|
+
field_dict.pop(self._meta.pk_name)
|
|
195
|
+
|
|
196
|
+
all_fields = self._meta.fields
|
|
197
|
+
|
|
198
|
+
if cls is None:
|
|
199
|
+
cls = self.__class__
|
|
200
|
+
|
|
201
|
+
created = False
|
|
202
|
+
|
|
203
|
+
pre_save.send(cls, instance=self)
|
|
204
|
+
|
|
205
|
+
if self.get_pk():
|
|
206
|
+
update = self.update(
|
|
207
|
+
self.get_pk(),
|
|
208
|
+
**field_dict
|
|
209
|
+
)
|
|
210
|
+
result = update.execute(self._handler)
|
|
211
|
+
else:
|
|
212
|
+
for k, v in all_fields.items():
|
|
213
|
+
if v.required is True and field_dict[v.name] is None:
|
|
214
|
+
raise ValueError('Missing mandatory field: ' + v.name)
|
|
215
|
+
|
|
216
|
+
insert = self.insert(idempotency_key=idempotency_key, **field_dict)
|
|
217
|
+
result = insert.execute(self._handler)
|
|
218
|
+
|
|
219
|
+
created = True
|
|
220
|
+
|
|
221
|
+
post_save.send(cls, instance=self, created=created)
|
|
222
|
+
|
|
223
|
+
for key, value in result.items():
|
|
224
|
+
setattr(self, key, value)
|
|
225
|
+
|
|
226
|
+
return result
|
|
227
|
+
|
|
228
|
+
@classmethod
|
|
229
|
+
def select(cls, *args, **kwargs):
|
|
230
|
+
return SelectQuery(cls, *args, **kwargs)
|
|
231
|
+
|
|
232
|
+
@classmethod
|
|
233
|
+
def create(cls, **query):
|
|
234
|
+
handler = query.pop('handler', get_default_handler())
|
|
235
|
+
inst = cls(**query)
|
|
236
|
+
inst.save(handler)
|
|
237
|
+
return inst
|
|
238
|
+
|
|
239
|
+
@classmethod
|
|
240
|
+
def update(cls, reference, **query):
|
|
241
|
+
return UpdateQuery(cls, reference, **query)
|
|
242
|
+
|
|
243
|
+
@classmethod
|
|
244
|
+
def insert(cls, idempotency_key, **query):
|
|
245
|
+
return InsertQuery(cls, idempotency_key=idempotency_key, **query)
|
|
246
|
+
|
|
247
|
+
@classmethod
|
|
248
|
+
def get(cls, *args, **kwargs):
|
|
249
|
+
return cls.select().get(*args, **kwargs)
|
|
250
|
+
|
|
251
|
+
def one(self, resource_model):
|
|
252
|
+
return resource_model.select().get(self.get_pk(),
|
|
253
|
+
resource_model=self.__class__,
|
|
254
|
+
handler=self.handler)
|
|
255
|
+
|
|
256
|
+
def list(self, resource_model, **kwargs):
|
|
257
|
+
return resource_model.select().list(self.get_pk(),
|
|
258
|
+
self.__class__,
|
|
259
|
+
handler=self.handler,
|
|
260
|
+
**kwargs)
|
|
261
|
+
|
|
262
|
+
@classmethod
|
|
263
|
+
def all(cls, *args, **kwargs):
|
|
264
|
+
return cls.select().all(*args, **kwargs)
|
|
265
|
+
|
|
266
|
+
@classmethod
|
|
267
|
+
def delete(cls, *args, **kwargs):
|
|
268
|
+
return DeleteQuery(cls, *args, **kwargs).execute()
|
|
269
|
+
|
|
270
|
+
def get_pk(self):
|
|
271
|
+
return getattr(self, self._meta.pk_name, None)
|
|
272
|
+
|
|
273
|
+
def get_pk_field(self):
|
|
274
|
+
return self._meta.fields[self._meta.pk_name]
|
|
275
|
+
|
|
276
|
+
def get_field_dict(self):
|
|
277
|
+
def get_field_val(field):
|
|
278
|
+
field_value = getattr(self, field.name)
|
|
279
|
+
if not self.get_pk() and field_value is None and field.default is not None:
|
|
280
|
+
if callable(field.default):
|
|
281
|
+
field_value = field.default()
|
|
282
|
+
else:
|
|
283
|
+
field_value = field.default
|
|
284
|
+
setattr(self, field.name, field_value)
|
|
285
|
+
return (field.name, field_value)
|
|
286
|
+
|
|
287
|
+
pairs = map(get_field_val, self._meta.fields.values())
|
|
288
|
+
|
|
289
|
+
return dict(pairs)
|
mangopay/compat.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# This code belongs to https://github.com/django/django/blob/master/django/utils/encoding.py
|
|
2
|
+
import six
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def python_2_unicode_compatible(klass):
|
|
6
|
+
"""
|
|
7
|
+
A decorator that defines __unicode__ and __str__ methods under Python 2.
|
|
8
|
+
Under Python 3 it does nothing.
|
|
9
|
+
|
|
10
|
+
To support Python 2 and 3 with a single code base, define a __str__ method
|
|
11
|
+
returning text and apply this decorator to the class.
|
|
12
|
+
"""
|
|
13
|
+
if six.PY2:
|
|
14
|
+
klass.__unicode__ = klass.__str__
|
|
15
|
+
klass.__str__ = lambda self: self.__unicode__().encode('utf-8')
|
|
16
|
+
return klass
|