MambuPy.rest.mambustruct

Base class for all Mambu objects.

Includes functionality to download such objects using GET requests to Mambu, and to POST requests to Mambu.

Some caching may be achieved. Please look at caching done at mambuproduct.AllMambuProducts class for an example of how caching should be done.

Official Mambu dev documentation at Mambu Developer Center: https://developer.mambu.com

You must configure your Mambu client in mambuconfig.py Please read the pydocs there for more information.

Some basic definitions:

  • MambuStruct refers to the parent class of all Mambu Objects and

  • MambuPy Mambu objects refers to any child of MambuStruct, usually defined at some mambu-somename- python module file. Sometimes referred as implemented MambuStruct or something fancy

  • Mambu entity refers to an entity retrieved via a request via Mambu REST API. It’s a more abstract thing in fact. Also may refer to entities on a relational database but the term table is preferred in this case.

Classes

MambuStruct(urlfunc[, entid])

This one is the Father of all Mambu objects at MambuPy.

class MambuPy.rest.mambustruct.MambuStruct(urlfunc, entid='', *args, **kwargs)[source]

Bases: object

This one is the Father of all Mambu objects at MambuPy.

It’s a dictionary-like structure by default, self.attr attribute holds all the info respondend by Mambu REST API.

This object is flexible enough to hold a list instead of a dictionary for certain objects holding iterators.

Further work is needed to hold list-like behaviour however.

RETRIES = 5

This one holds the maximum number of retries for requests to Mambu.

Some networks have a lot of lag, so a safe maximum has been added here. If after RETRIES attempts to connect to Mambu, MambuPy can’t connect, a MambuCommError will be raised.

__contains__(item)[source]

Dict-like and List-like behaviour

__copy_args(args, kwargs)
__credentials()
__data

JSON data to be sent to Mambu for POST/PATCH requests.

__debug

Debug flag.

Todo

not currently furtherly implemented

__delitem__(key)[source]

Dict-like del key

__dict__ = mappingproxy({'__module__': 'MambuPy.rest.mambustruct', '__doc__': "This one is the Father of all Mambu objects at MambuPy.\n\n    It's a dictionary-like structure by default, self.attr attribute\n    holds all the info respondend by Mambu REST API.\n\n    This object is flexible enough to hold a list instead of a\n    dictionary for certain objects holding iterators.\n\n    Further work is needed to hold list-like behaviour however.\n    ", 'RETRIES': 5, 'serialize_fields': <staticmethod object>, '__getitem__': <function MambuStruct.__getitem__>, '__setitem__': <function MambuStruct.__setitem__>, '__delitem__': <function MambuStruct.__delitem__>, '__hash__': <function MambuStruct.__hash__>, '__getattribute__': <function MambuStruct.__getattribute__>, '__setattr__': <function MambuStruct.__setattr__>, '__repr__': <function MambuStruct.__repr__>, '__str__': <function MambuStruct.__str__>, '__len__': <function MambuStruct.__len__>, '__eq__': <function MambuStruct.__eq__>, 'has_key': <function MambuStruct.has_key>, '__contains__': <function MambuStruct.__contains__>, 'get': <function MambuStruct.get>, 'keys': <function MambuStruct.keys>, 'items': <function MambuStruct.items>, 'init': <function MambuStruct.init>, 'serialize_struct': <function MambuStruct.serialize_struct>, '_MambuStruct__copy_args': <function MambuStruct.__copy_args>, '__init__': <function MambuStruct.__init__>, '_MambuStruct__request': <function MambuStruct.__request>, '_MambuStruct__process_jsonresp': <function MambuStruct.__process_jsonresp>, '_MambuStruct__request_and_process': <function MambuStruct.__request_and_process>, '_is_mambu_error': <function MambuStruct._is_mambu_error>, '_MambuStruct__credentials': <function MambuStruct.__credentials>, 'connect': <function MambuStruct.connect>, '_request_with_method': <function MambuStruct._request_with_method>, '_MambuStruct__massage_appropiate_format': <function MambuStruct.__massage_appropiate_format>, '_process_fields': <function MambuStruct._process_fields>, 'preprocess': <function MambuStruct.preprocess>, 'postprocess': <function MambuStruct.postprocess>, '_convert_data_to_pytype': <function MambuStruct._convert_data_to_pytype>, '_convert_dict_to_pytypes': <function MambuStruct._convert_dict_to_pytypes>, 'convert_dict_to_attrs': <function MambuStruct.convert_dict_to_attrs>, 'util_date_format': <function MambuStruct.util_date_format>, 'create': <function MambuStruct.create>, 'update': <function MambuStruct.update>, 'update_patch': <function MambuStruct.update_patch>, 'update_post': <function MambuStruct.update_post>, 'upload_document': <function MambuStruct.upload_document>, '__dict__': <attribute '__dict__' of 'MambuStruct' objects>, '__weakref__': <attribute '__weakref__' of 'MambuStruct' objects>, '__annotations__': {}})
__eq__(other)[source]

Very basic way to compare to Mambu objects.

Only looking at their EncodedKey field (its primary key on the Mambu DB).

Todo

a lot of improvements may be done here.

__formato_fecha

The default date format to be used for any datettime elements on the attrs attribute.

Remember to use valid Python datetime strftime formats.

__getattribute__(name)[source]

Object-like get attribute

When accessing an attribute, tries to find it in the attrs dictionary, so now MambuStruct may act not only as a dict-like structure, but as a full object-like too (this is the getter side).

__getitem__(key)[source]

Dict-like key query

__hash__()[source]

Hash of the object

__inilimit

Limit the number of elements to be retrieved from Mambu on GET requests.

Defaults to 0 which means (for the connect method) that you don’t care how many elements Mambu has, you wish to retrieve them all.

__init__(urlfunc, entid='', *args, **kwargs)[source]

Initializes a new Mambu object.

Parameters:
  • urlfunc (str) – is the only required parameter. The urlfunc returns a string of the URL to make a request to Mambu. You may read about the valid urlfuncs supported by MambuPy at mambuutil.py

  • entid (str) – is the usual ID of a Mambu entity you like to GET from Mambu. The ID of a loan account, a client, a group, etc. Or the transactions or repayments of certain loan account. It’s an optional parameter because the iterable Mambu objects don’t need an specific ID, just some other filtering parameters supported on the urlfunc function.

If you send a None urlfunc, the object will be configured, but won’t connect to Mambu, never. Useful for iterables that configure their elements but can’t or won’t need Mambu to send further information. See mamburepayment.MambuRepayments for an example of this.

Should you need to add support for more functionality, add them at mambuutuil.

Many other arguments may be sent here to further configure the Mambu object or the response by Mambu REST API:

  • debug flag (currently not implemented, just stored on the object)

  • connect flag, to optionally omit the connection to Mambu (see the init() (with no underscores) method pydoc)

  • data parameter for POST requests (see connect() method pydoc)

  • date_format parameter (see util_date_format() method pydoc)

Also, parameters to be sent to Mambu on the request, such as:

  • limit parameter (for pagination, see connect() method pydoc). If 0 (default) tells connect to auto-paginate. All else is used as given for manual pagination (all along with the offset argument too)

  • offset parameter (for pagination, see connect() method pydoc)

  • fullDetails, accountState and other filtering parameters (see mambuutil pydocs)

  • user, password, url to connect to Mambu, to bypass mambuconfig configurations (see mambuutil pydoc)

__len__()[source]

Length of the attrs attribute.

If dict-like (not iterable), it’s the number of keys holded on the attrs dictionary. If list-like (iterable), it’s the number of elements of the attrs list.

__massage_appropiate_format()
__method

REST method to use when calling connect

__module__ = 'MambuPy.rest.mambustruct'
__offset

When retrieving several elements from Mambu on GET requests, offset for the first element to be retrieved.

__process_jsonresp(jsonresp, limit, jsresp)
__repr__()[source]

Mambu object repr tells the class name and the usual ‘id’ for it.

If an iterable, it instead gives its length.

__request(url, user, pwd)

Method used in connect, for make the request.

Uses self.__data dictionary to feed the body for POST and PATCH requests. If there is no data in self.__data, it defaults to a GET request.

Parameters:
  • url (str) – url to make request, changed with iri_to_uri

  • user (str) – user to authenticate for requests

  • pwd (str) – password to authenticate for requests

Returns:

The response of the request (json)

__request_and_process(jsresp, url, user, pwd, limit, offset)
__setattr__(name, value)[source]

Object-like set attribute

When setting an attribute, tries to set it in the attrs dictionary, so now MambuStruct acts not only as a dict-like structure, but as a full object-like too (this is the setter side).

__setitem__(key, value)[source]

Dict-like set

__str__()[source]

Mambu object str gives a string representation of the attrs attribute.

__urlfunc

The given urlfunc argument is saved here.

It’s used at the connect() method, when called.

__weakref__

list of weak references to the object (if defined)

_convert_data_to_pytype(data)[source]

“Python built-in types: ints, floats, or even datetimes. If it cannot convert it to a built-in type, leave it as string, or as-is. There may be nested Mambu objects here! This are the recursion base cases!

_convert_dict_to_pytypes(data)[source]

Recursively convert the fields on the data given to a python object.

_is_mambu_error(jsresp)[source]
_process_fields()[source]

Default info massage to appropiate format/style.

This processing is called on preprocess and postprocess, AKA before and after conversion of fields to appropiate format/style.

Perfect example: custom fields on certain objects is a mess (IMHO) when retrieved from Mambu, so some easiness is implemented here to access them. See some of this objects modules and pydocs for further info.

Tasks done here:

  • Each custom field is given a ‘name’ key that holds the field name, and for each keyed name, the value of the custom field is assigned. Each pair of custom field name/value is entered as a new property on the main dictionary, allowing an easy access to them, not nested inside a pretty dark ‘customInformation/Values’ list.

  • Every item on the attrs dictionary gets stripped from trailing spaces (useful when users make typos).

PLEASE REMEMBER! whenever you call postprocess on inherited classes you should call this method too, or else you lose the effect of the tasks done here.

_request_with_method(method, data, *args, **kwargs)[source]

Method to do a specific request on the current Mambu entity

connect(*args, **kwargs)[source]

Connect to Mambu, make the request to the REST API.

If there’s no urlfunc to use, nothing is done here.

When done, initializes the attrs attribute of the Mambu object by calling the init method. Please refer to that code and pydoc for further information.

Uses urllib module to connect. Since all Mambu REST API responses are json, uses json module to translate the response to a valid python object (dictionary or list).

When Mambu returns a response with returnCode and returnStatus fields, it means something went wrong with the request, and a MambuError is thrown detailing the error given by Mambu itself.

If you need to make a POST request, send a data argument to the new Mambu object.

Provides to prevent errors due to using special chars on the request URL. See mambuutil.iri_to_uri() method pydoc for further info.

Provides to prevent errors due to using special chars on the parameters of a POST request. See mambuutil.encoded_dict() method pydoc for further info.

For every request done, the request counter Singleton is increased.

Includes retry logic, to provide for a max number of connection failures with Mambu. If maximum retries are reached, MambuCommError is thrown.

Includes pagination code. Mambu supports a max of 500 elements per response. Such an ugly detail is wrapped here so further pagination logic is not needed above here. You need a million elements? you got them by making several 500 elements requests later joined together in a sigle list. Just send a limit=0 (default) and that’s it.

Todo

improve raised exception messages. Sometimes MambuCommErrors are thrown due to reasons not always clear when catched down the road, but that perhaps may be noticed in here and aren’t fully reported to the user. Specially serious on retries-MambuCommError situations (the except Exception that increases the retries counter is not saving the exception message, just retrying).

Todo

what about using decorators for the retry and for the window logic? (https://www.oreilly.com/ideas/5-reasons-you-need-to-learn-to-write-python-decorators # Reusing impossible-to-reuse code)

convert_dict_to_attrs(*args, **kwargs)[source]

Each element on the attrs attribute gest converted to a proper python object, depending on type.

Some default constantFields are left as is (strings), because they are better treated as strings.

create(data, *args, **kwargs)[source]

Creates an entity in Mambu

This method must be implemented in child classes

Parameters:

data (dictionary) – dictionary with data to send, this dictionary is specific for each Mambu entity

custom_field_name

custom_field_name attribute.

entid

ID of the Mambu entity, or empty if not wanting a specific entity to be GETted

get(key, default=None)[source]

Dict-like behaviour

has_key(key)[source]

Dict-like behaviour

init(attrs={}, *args, **kwargs)[source]

Default initialization from a dictionary responded by Mambu

in to the elements of the Mambu object.

It assings the response to attrs attribute and converts each of its elements from a string to an adequate python object: number, datetime, etc.

Basically it stores the response on the attrs attribute, then runs some customizable preprocess method, then runs convert_dict_to_attrs method to convert the string elements to an adequate python object, then a customizable postprocess method.

It also executes each method on the ‘methods’ attribute given on instantiation time, and sets new customizable ‘properties’ to the object.

Why not on __init__? two reasons:

  • __init__ optionally connects to Mambu, if you don’t connect to Mambu, the Mambu object will be configured but it won’t have any Mambu info on it. Only when connected, the Mambu object will be initialized, here.

    Useful to POST several times the same Mambu object. You make a POST request over and over again by calling it’s connect() method every time you wish. This init method will configure the response in to the attrs attribute each time.

    You may also wish to update the info on a previously initialized Mambu object and refresh it with what Mambu now has. Instead of building a new object, you just connect() again and it will be refreshed.

  • Iterable Mambu objects (lists) do not initialize here, the iterable Mambu object __init__ goes through each of its elements and then initializes with this code one by one. Please look at some Mambu iterable object code and pydoc for more details.

items()[source]

Dict-like behaviour

keys()[source]

Dict-like behaviour

postprocess()[source]

Each MambuStruct implementation may massage the info on the Mambu response after conversion to an appropiate format/style adequate for its needs.

preprocess()[source]

Each MambuStruct implementation may massage the info on the Mambu response before conversion to an appropiate format/style adequate for its needs.

rc

Request Count Singleton

static serialize_fields(data)[source]

Turns every attribute of the Mambu object in to a string representation.

If the object is an iterable one, it goes down to each of its elements and turns its attributes too, recursively.

The base case is when it’s a MambuStruct class (this one) so it just ‘serializes’ the attr atribute. Refer to MambuStruct.serialize_struct pydoc.

This is perhaps the worst way to do it, still looking for a better way.

serialize_struct()[source]

Makes a string from each element on the attrs attribute.

Read the class attribute MambuStruct.serialize_fields pydoc for more info.

It DOES NOT serializes the class, for persistence or network transmission, just the fields on the attrs attribute.

Remember that attrs may have any type of elements: numbers, strings, datetimes, Mambu objects, etc. This is a way to convert it to a string in an easy, however ugly, way.

WARNING: it may fall in a stack overflow

Todo

check recursion levels.

update(data, *args, **kwargs)[source]

Downloads an update made to an entity in Mambu.

This method must be implemented in child classes.

Parameters:

data (dictionary) – data to send

update_patch(data, *args, **kwargs)[source]

Updates an entity in Mambu

This method must be implemented in child classes

Parameters:

data (dictionary) – dictionary with data to send, this dictionary is specific for each Mambu entity

update_post(data, *args, **kwargs)[source]

Updates an entity in Mambu

This method must be implemented in child classes

Parameters:

data (dictionary) – dictionary with data to send, this dictionary is specific for each Mambu entity

upload_document(data, *args, **kwargs)[source]

Uploads a document in Mambu

This method must be implemented in child classes https://support.mambu.com/docs/attachments-api#post-attachments

Parameters:

data (dictionary) – dictionary with data to send

Example: data = {

“document”:{

“documentHolderKey” : self.encodedKey, “documentHolderType” : “LOAN_ACCOUNT”, # CLIENT, GROUP, USER, BRANCH… “name” : “loan_resume”, “type” : “pdf”,

}, “documentContent” : “[‘encodedBase64_file’]”,

}

util_date_format(field, formato=None)[source]

Converts a datetime field to a datetime using some specified format.

What this really means is that, if specified format includes only for instance just year and month, day and further info gets ignored and the objects get a datetime with year and month, and day 1, hour 0, minute 0, etc.

A useful format may be %Y%m%d, then the datetime objects effectively translates into date objects alone, with no relevant time information.

PLEASE BE AWARE, that this may lose useful information for your datetimes from Mambu. Read this for why this may be a BAD idea: https://julien.danjou.info/blog/2015/python-and-timezones