File: util.py

package info (click to toggle)
python-marathon 0.13.0-7
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 460 kB
  • sloc: python: 1,969; makefile: 185; sh: 58
file content (81 lines) | stat: -rw-r--r-- 2,330 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import collections
import datetime
import logging

try:
    import json
except ImportError:
    import simplejson as json
import re


def get_log():
    return logging.getLogger(__name__.split('.')[0])


class MarathonJsonEncoder(json.JSONEncoder):

    """Custom JSON encoder for Marathon object serialization."""

    def default(self, obj):
        if hasattr(obj, 'json_repr'):
            return self.default(obj.json_repr())

        if isinstance(obj, datetime.datetime):
            return obj.strftime('%Y-%m-%dT%H:%M:%S.%fZ')

        if isinstance(obj, collections.abc.Iterable) and not isinstance(obj, str):
            try:
                return {k: self.default(v) for k, v in obj.items()}
            except AttributeError:
                return [self.default(e) for e in obj]

        return obj


class MarathonMinimalJsonEncoder(json.JSONEncoder):

    """Custom JSON encoder for Marathon object serialization."""

    def default(self, obj):
        if hasattr(obj, 'json_repr'):
            return self.default(obj.json_repr(minimal=True))

        if isinstance(obj, datetime.datetime):
            return obj.strftime('%Y-%m-%dT%H:%M:%S.%fZ')

        if isinstance(obj, collections.abc.Iterable) and not isinstance(obj, str):
            try:
                return {k: self.default(v) for k, v in obj.items() if (v or v in (False, 0))}
            except AttributeError:
                return [self.default(e) for e in obj if (e or e in (False, 0))]

        return obj


def to_camel_case(snake_str):
    words = snake_str.split('_')
    return words[0] + ''.join(w.capitalize() for w in words[1:])


def to_snake_case(camel_str):
    s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', camel_str)
    return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()


DATETIME_FORMATS = [
    '%Y-%m-%dT%H:%M:%S.%fZ',
    '%Y-%m-%dT%H:%M:%SZ',  # Marathon omits milliseconds when they would be .000
]


def to_datetime(timestamp):
    if (timestamp is None or isinstance(timestamp, datetime.datetime)):
        return timestamp
    else:
        for fmt in DATETIME_FORMATS:
            try:
                return datetime.datetime.strptime(timestamp, fmt).replace(tzinfo=datetime.timezone.utc)
            except ValueError:
                pass
        raise ValueError(f'Unrecognized datetime format: {timestamp}')