|
2 | 2 | from __future__ import unicode_literals |
3 | 3 |
|
4 | 4 | import re |
| 5 | +import importlib |
| 6 | +import warnings |
5 | 7 |
|
6 | 8 | from collections import OrderedDict |
7 | 9 | from copy import deepcopy |
| 10 | +from json import dumps |
8 | 11 | from six import iteritems |
9 | 12 |
|
10 | 13 | from ._http import HTTPStatus |
|
14 | 17 | ALL_CAP_RE = re.compile('([a-z0-9])([A-Z])') |
15 | 18 |
|
16 | 19 |
|
17 | | -__all__ = ('merge', 'camel_to_dash', 'default_id', 'not_none', 'not_none_sorted', 'unpack') |
| 20 | +__all__ = ('preload_serializer', 'importer', 'merge', 'camel_to_dash', 'default_id', 'not_none', 'not_none_sorted', 'unpack') |
| 21 | + |
| 22 | + |
| 23 | +def preload_serializer(app): |
| 24 | + ''' |
| 25 | + Preload the json serializer for the given ``app``. |
| 26 | +
|
| 27 | + :param flask.Flask app: The flask application object |
| 28 | + ''' |
| 29 | + custom_serializer = app.config.get('RESTPLUS_JSON_SERIALIZER', None) |
| 30 | + serializer = None |
| 31 | + |
| 32 | + # If the user wants to use a custom serializer, let it be |
| 33 | + if custom_serializer: |
| 34 | + try: |
| 35 | + serializer = importer(custom_serializer, 'dumps') |
| 36 | + except ImportError: |
| 37 | + if '.' in custom_serializer: |
| 38 | + mod, func = custom_serializer.rsplit('.', 1) |
| 39 | + try: |
| 40 | + serializer = importer(mod, func) |
| 41 | + except ImportError: |
| 42 | + warnings.warn("Unable to load custom serializer '{}', falling back to " |
| 43 | + "'json.dumps'".format(custom_serializer), |
| 44 | + UserWarning) |
| 45 | + |
| 46 | + # fallback, no serializer found so far, use the default one |
| 47 | + if serializer is None: |
| 48 | + serializer = dumps |
| 49 | + app.config['RESTPLUS_CACHED_SERIALIZER'] = serializer |
| 50 | + |
| 51 | + |
| 52 | +def importer(mod_name, obj_name, default=None): |
| 53 | + ''' |
| 54 | + Import the given ``obj_name`` from the given ``mod_name``. |
| 55 | +
|
| 56 | + :param str mod_name: Module from which to import the ``obj_name`` |
| 57 | + :param str obj_name: Object to import from ``mod_name`` |
| 58 | + :param object default: Default object to return |
| 59 | +
|
| 60 | + :return: Imported object |
| 61 | + ''' |
| 62 | + imported = importlib.import_module(mod_name) |
| 63 | + return getattr(imported, obj_name, default) |
18 | 64 |
|
19 | 65 |
|
20 | 66 | def merge(first, second): |
|
0 commit comments