From 60bd56b91cb5ae429530740c0c6d63ae7aa6c258 Mon Sep 17 00:00:00 2001 From: Dan Peschman Date: Thu, 15 Jan 2015 22:42:59 +0000 Subject: [PATCH 1/6] python3: support more iso8601 datetime formats - http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#date.and.time.format.examples --- src/main/resources/python3/swagger.mustache | 38 ++++++++++++++++----- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/main/resources/python3/swagger.mustache b/src/main/resources/python3/swagger.mustache index a01b69794ee..ae8d671671a 100644 --- a/src/main/resources/python3/swagger.mustache +++ b/src/main/resources/python3/swagger.mustache @@ -43,7 +43,6 @@ class ApiClient: data = None - if queryParams: # Need to remove None values, these should not be sent sentQueryParams = {} @@ -119,6 +118,34 @@ class ApiClient: for (key, val) in objDict.items() if key != 'swaggerTypes'} + def _iso8601Format(self, timesep, microsecond, zulu): + """Format for parsing a datetime string with given properties. + + Args: + timesep -- string separating time from date ('T' or 't') + microsecond -- microsecond portion of time ('.XXX') + zulu -- 'Z' or 'z' for UTC, or None for time offset (+/-XX:XX) + + Returns: + str - format string for datetime.strptime""" + + return '%Y-%m-%d{}%H:%M:%S{}{}'.format( + timesep, + '.%f' if microsecond else '', + zulu or '%z') + + # http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14 + _iso8601Regex = re.compile( + r'^\d\d\d\d-\d\d-\d\d([Tt])\d\d:\d\d:\d\d(\.\d+)?(([Zz])|(\+|-)\d\d:?\d\d)$') + + def _parseDatetime(self, d): + m = ApiClient._iso8601Regex.match(d) + timesep, microsecond, offset, zulu, plusminus = m.groups() + format = self._iso8601Format(timesep, microsecond, zulu) + if not zulu: + d = d.rsplit(sep=plusminus, maxsplit=1)[0] + offset.replace(':', '') + return datetime.datetime.strptime(d, format) + def deserialize(self, obj, objClass): """Derialize a JSON string into an object. @@ -145,11 +172,7 @@ class ApiClient: if objClass in [int, float, dict, list, str, bool]: return objClass(obj) elif objClass == datetime: - # Server will always return a time stamp in UTC, but with - # trailing +0000 indicating no offset from UTC. So don't process - # last 5 characters. - return datetime.datetime.strptime(obj[:-5], - "%Y-%m-%dT%H:%M:%S.%f") + return self._parseDatetime(obj) instance = objClass() @@ -167,8 +190,7 @@ class ApiClient: value = value setattr(instance, attr, value) elif (attrType == 'datetime'): - setattr(instance, attr, datetime.datetime.strptime(value[:-5], - "%Y-%m-%dT%H:%M:%S.%f")) + setattr(instance, attr, self._parseDatetime(value)) elif 'list[' in attrType: match = re.match('list\[(.*)\]', attrType) subClass = match.group(1) From 527fca5a8bc9f884e72a586457b571c2d902b7ef Mon Sep 17 00:00:00 2001 From: Dan Peschman Date: Thu, 15 Jan 2015 23:19:01 +0000 Subject: [PATCH 2/6] python3 parseDatetime: return None if passed None --- src/main/resources/python3/swagger.mustache | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/resources/python3/swagger.mustache b/src/main/resources/python3/swagger.mustache index ae8d671671a..4986b8548df 100644 --- a/src/main/resources/python3/swagger.mustache +++ b/src/main/resources/python3/swagger.mustache @@ -139,6 +139,8 @@ class ApiClient: r'^\d\d\d\d-\d\d-\d\d([Tt])\d\d:\d\d:\d\d(\.\d+)?(([Zz])|(\+|-)\d\d:?\d\d)$') def _parseDatetime(self, d): + if d is None: + return None m = ApiClient._iso8601Regex.match(d) timesep, microsecond, offset, zulu, plusminus = m.groups() format = self._iso8601Format(timesep, microsecond, zulu) From 42ad403e5eb91b917148768a814760d4fa405d85 Mon Sep 17 00:00:00 2001 From: Dan Peschman Date: Fri, 16 Jan 2015 23:09:54 +0000 Subject: [PATCH 3/6] python3 parseDatetime: return None if passed '' --- src/main/resources/python3/swagger.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/python3/swagger.mustache b/src/main/resources/python3/swagger.mustache index 4986b8548df..8985d1a1b41 100644 --- a/src/main/resources/python3/swagger.mustache +++ b/src/main/resources/python3/swagger.mustache @@ -139,7 +139,7 @@ class ApiClient: r'^\d\d\d\d-\d\d-\d\d([Tt])\d\d:\d\d:\d\d(\.\d+)?(([Zz])|(\+|-)\d\d:?\d\d)$') def _parseDatetime(self, d): - if d is None: + if not d: return None m = ApiClient._iso8601Regex.match(d) timesep, microsecond, offset, zulu, plusminus = m.groups() From 711d2c8cf46afa40444da6d4df2a7b441a0230d6 Mon Sep 17 00:00:00 2001 From: Dan Peschman Date: Fri, 16 Jan 2015 23:44:02 +0000 Subject: [PATCH 4/6] revert previous: no special handling for '' in python3 parseDatetime --- src/main/resources/python3/swagger.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/python3/swagger.mustache b/src/main/resources/python3/swagger.mustache index 8985d1a1b41..4986b8548df 100644 --- a/src/main/resources/python3/swagger.mustache +++ b/src/main/resources/python3/swagger.mustache @@ -139,7 +139,7 @@ class ApiClient: r'^\d\d\d\d-\d\d-\d\d([Tt])\d\d:\d\d:\d\d(\.\d+)?(([Zz])|(\+|-)\d\d:?\d\d)$') def _parseDatetime(self, d): - if not d: + if d is None: return None m = ApiClient._iso8601Regex.match(d) timesep, microsecond, offset, zulu, plusminus = m.groups() From 4198779b5bf137cd362eb5571a1d68df268d093f Mon Sep 17 00:00:00 2001 From: Dan Peschman Date: Sat, 17 Jan 2015 00:41:37 +0000 Subject: [PATCH 5/6] python3: support datetime produced by datetime.isoformat like '2015-01-17T00:15:29.515' --- src/main/resources/python3/swagger.mustache | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/resources/python3/swagger.mustache b/src/main/resources/python3/swagger.mustache index 4986b8548df..3b00a14dc95 100644 --- a/src/main/resources/python3/swagger.mustache +++ b/src/main/resources/python3/swagger.mustache @@ -118,12 +118,13 @@ class ApiClient: for (key, val) in objDict.items() if key != 'swaggerTypes'} - def _iso8601Format(self, timesep, microsecond, zulu): + def _iso8601Format(self, timesep, microsecond, offset, zulu): """Format for parsing a datetime string with given properties. Args: timesep -- string separating time from date ('T' or 't') microsecond -- microsecond portion of time ('.XXX') + offset -- time offset (+/-XX:XX) or None zulu -- 'Z' or 'z' for UTC, or None for time offset (+/-XX:XX) Returns: @@ -132,19 +133,21 @@ class ApiClient: return '%Y-%m-%d{}%H:%M:%S{}{}'.format( timesep, '.%f' if microsecond else '', - zulu or '%z') + zulu or ('%z' if offset else '')) # http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14 _iso8601Regex = re.compile( - r'^\d\d\d\d-\d\d-\d\d([Tt])\d\d:\d\d:\d\d(\.\d+)?(([Zz])|(\+|-)\d\d:?\d\d)$') + r'^\d\d\d\d-\d\d-\d\d([Tt])\d\d:\d\d:\d\d(\.\d+)?(([Zz])|(\+|-)\d\d:?\d\d)?$') def _parseDatetime(self, d): if d is None: return None m = ApiClient._iso8601Regex.match(d) + if not m: + raise Exception('datetime regex match failed "%s"' % d) timesep, microsecond, offset, zulu, plusminus = m.groups() - format = self._iso8601Format(timesep, microsecond, zulu) - if not zulu: + format = self._iso8601Format(timesep, microsecond, offset, zulu) + if offset and not zulu: d = d.rsplit(sep=plusminus, maxsplit=1)[0] + offset.replace(':', '') return datetime.datetime.strptime(d, format) From ec995838fba479fa35e9926379e26010ac83731a Mon Sep 17 00:00:00 2001 From: Dan Peschman Date: Sat, 24 Jan 2015 21:58:33 +0000 Subject: [PATCH 6/6] python3: support PATCH verb for partial updates - http://tools.ietf.org/html/rfc5789 --- src/main/resources/python3/swagger.mustache | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/python3/swagger.mustache b/src/main/resources/python3/swagger.mustache index 3b00a14dc95..722a60a634d 100644 --- a/src/main/resources/python3/swagger.mustache +++ b/src/main/resources/python3/swagger.mustache @@ -56,7 +56,7 @@ class ApiClient: #Options to add statements later on and for compatibility pass - elif method in ['POST', 'PUT', 'DELETE']: + elif method in ['PATCH', 'POST', 'PUT', 'DELETE']: if postData: headers['Content-type'] = 'application/json'