|
6 | 6 | from __future__ import print_function |
7 | 7 | from __future__ import unicode_literals |
8 | 8 |
|
9 | | -import time |
10 | | -import random |
11 | | - |
| 9 | +import datetime |
12 | 10 | import json |
| 11 | +import random |
13 | 12 | import socket |
| 13 | +import struct |
| 14 | +import time |
| 15 | + |
| 16 | +import msgpack |
14 | 17 | import requests |
15 | 18 | import requests.exceptions |
16 | 19 | from six.moves import xrange |
@@ -144,7 +147,7 @@ def __init__(self, |
144 | 147 |
|
145 | 148 | self._headers = { |
146 | 149 | 'Content-Type': 'application/json', |
147 | | - 'Accept': 'text/plain' |
| 150 | + 'Accept': 'application/x-msgpack' |
148 | 151 | } |
149 | 152 |
|
150 | 153 | @property |
@@ -293,13 +296,30 @@ def request(self, url, method='GET', params=None, data=None, |
293 | 296 | time.sleep((2 ** _try) * random.random() / 100.0) |
294 | 297 | if not retry: |
295 | 298 | raise |
| 299 | + |
| 300 | + type_header = response.headers and response.headers.get("Content-Type") |
| 301 | + if type_header == "application/x-msgpack" and response.content: |
| 302 | + response._msgpack = msgpack.unpackb( |
| 303 | + packed=response.content, |
| 304 | + ext_hook=_msgpack_parse_hook, |
| 305 | + raw=False) |
| 306 | + else: |
| 307 | + response._msgpack = None |
| 308 | + |
| 309 | + def reformat_error(response): |
| 310 | + if response._msgpack: |
| 311 | + return json.dumps(response._msgpack, separators=(',', ':')) |
| 312 | + else: |
| 313 | + return response.content |
| 314 | + |
296 | 315 | # if there's not an error, there must have been a successful response |
297 | 316 | if 500 <= response.status_code < 600: |
298 | | - raise InfluxDBServerError(response.content) |
| 317 | + raise InfluxDBServerError(reformat_error(response)) |
299 | 318 | elif response.status_code == expected_response_code: |
300 | 319 | return response |
301 | 320 | else: |
302 | | - raise InfluxDBClientError(response.content, response.status_code) |
| 321 | + err_msg = reformat_error(response) |
| 322 | + raise InfluxDBClientError(err_msg, response.status_code) |
303 | 323 |
|
304 | 324 | def write(self, data, params=None, expected_response_code=204, |
305 | 325 | protocol='json'): |
@@ -450,10 +470,11 @@ def query(self, |
450 | 470 | expected_response_code=expected_response_code |
451 | 471 | ) |
452 | 472 |
|
453 | | - if chunked: |
454 | | - return self._read_chunked_response(response) |
455 | | - |
456 | | - data = response.json() |
| 473 | + data = response._msgpack |
| 474 | + if not data: |
| 475 | + if chunked: |
| 476 | + return self._read_chunked_response(response) |
| 477 | + data = response.json() |
457 | 478 |
|
458 | 479 | results = [ |
459 | 480 | ResultSet(result, raise_errors=raise_errors) |
@@ -1119,3 +1140,12 @@ def _parse_netloc(netloc): |
1119 | 1140 | 'password': info.password or None, |
1120 | 1141 | 'host': info.hostname or 'localhost', |
1121 | 1142 | 'port': info.port or 8086} |
| 1143 | + |
| 1144 | + |
| 1145 | +def _msgpack_parse_hook(code, data): |
| 1146 | + if code == 5: |
| 1147 | + (epoch_s, epoch_ns) = struct.unpack(">QI", data) |
| 1148 | + timestamp = datetime.datetime.utcfromtimestamp(epoch_s) |
| 1149 | + timestamp += datetime.timedelta(microseconds=(epoch_ns / 1000)) |
| 1150 | + return timestamp.isoformat() + 'Z' |
| 1151 | + return msgpack.ExtType(code, data) |
0 commit comments