diff --git a/README.rst b/README.rst index 340cf9f..718144c 100644 --- a/README.rst +++ b/README.rst @@ -32,7 +32,7 @@ You can write measurements in a few different ways, but writing a single .. code:: python from inflow import Client - client = Client('http://username:pass@localhost:8086/databasename') + client = Client('http://username:pass@localhost:8086', db='databasename') client.write('temperature', value=21.3) For more examples and docs on how to use the client, refer to the Measurements diff --git a/docs/source/client.rst b/docs/source/client.rst index addb2a2..9dfd449 100644 --- a/docs/source/client.rst +++ b/docs/source/client.rst @@ -12,7 +12,7 @@ You can write measurements in a few different ways, but writing a single .. code:: python from inflow import Client - client = Client('http://username:pass@localhost:8086/databasename') + client = Client('http://username:pass@localhost:8086', db='databasename') client.write('temperature', value=21.3) No time is specified in the above example, so inflow automatically set's the @@ -25,7 +25,7 @@ A more complex example of writing a single measurement: from inflow import Client - client = Client('http://username:pass@localhost:8086/databasename') + client = Client('http://username:pass@localhost:8086', db='databasename') client.write( 'temperature' @@ -43,7 +43,7 @@ Writing multiple measurements is also possible: from inflow import Client, Measurement - client = Client('http://username:pass@localhost:8086/databasename') + client = Client('http://username:pass@localhost:8086', db='databasename') client.write([ Measurement( @@ -72,7 +72,7 @@ However, this is a bit verbose. That's why you can also do this: from inflow import Client, Measurement - client = Client('http://username:pass@localhost:8086/databasename') + client = Client('http://username:pass@localhost:8086', db='databasename') temperature = Measurement( name='temperature', diff --git a/examples/different_precision.py b/examples/different_precision.py index ef394c3..dd6602b 100755 --- a/examples/different_precision.py +++ b/examples/different_precision.py @@ -1,6 +1,8 @@ #!/usr/bin/env python from inflow import Client -client = Client('http://username:pass@localhost:8086/databasename', - precision='ms') -client.write('temperature', value=21.3, timestamp=1476191999000) + +client = Client( + "http://username:pass@localhost:8086", db="databasename", precision="ms" +) +client.write("temperature", value=21.3, timestamp=1476191999000) diff --git a/examples/explicit_retention_policy.py b/examples/explicit_retention_policy.py index dea7aa3..d83a15e 100755 --- a/examples/explicit_retention_policy.py +++ b/examples/explicit_retention_policy.py @@ -2,7 +2,10 @@ from inflow import Client -client = Client('http://username:pass@localhost:8086/databasename', - retention_policy='rp_four_weeks') +client = Client( + "http://username:pass@localhost:8086", + db="databasename", + retention_policy="rp_four_weeks", +) -client.write('temperature', value=21.3) +client.write("temperature", value=21.3) diff --git a/examples/query_measurements.py b/examples/query_measurements.py index b02835a..ec26282 100755 --- a/examples/query_measurements.py +++ b/examples/query_measurements.py @@ -2,6 +2,6 @@ from inflow import Client -client = Client('http://username:pass@localhost:8086/databasename') +client = Client("http://username:pass@localhost:8086", db="databasename") results = client.query('SELECT * FROM "temperatures"') # Results will contain a list of dicts for each returned measurement. diff --git a/examples/query_measurements_unix.py b/examples/query_measurements_unix.py index cf1d693..b30827e 100755 --- a/examples/query_measurements_unix.py +++ b/examples/query_measurements_unix.py @@ -2,5 +2,5 @@ from inflow import Client -client = Client('http://username:pass@localhost:8086/databasename') -results = client.query('SELECT * FROM "temperatures"', epoch='s') +client = Client("http://username:pass@localhost:8086", db="databasename") +results = client.query('SELECT * FROM "temperatures"', epoch="s") diff --git a/examples/single_write.py b/examples/single_write.py index 167d5d5..d59a849 100755 --- a/examples/single_write.py +++ b/examples/single_write.py @@ -1,5 +1,6 @@ #!/usr/bin/env python from inflow import Client -client = Client('http://username:pass@localhost:8086/databasename') -client.write('temperature', value=21.3) + +client = Client("http://username:pass@localhost:8086", db="databasename") +client.write("temperature", value=21.3) diff --git a/examples/single_write_more.py b/examples/single_write_more.py index 96654b2..9468fee 100755 --- a/examples/single_write_more.py +++ b/examples/single_write_more.py @@ -2,14 +2,11 @@ from inflow import Client -client = Client('http://username:pass@localhost:8086/databasename') +client = Client("http://username:pass@localhost:8086", db="databasename") client.write( - 'temperature', - tags={ - 'location': 'groningen', - 'sensor_type': 'ni1000' - }, + "temperature", + tags={"location": "groningen", "sensor_type": "ni1000"}, value=21.3, - timestamp=1475845863 + timestamp=1475845863, ) diff --git a/examples/single_write_retention_policy.py b/examples/single_write_retention_policy.py index 61ca34f..205f2a2 100755 --- a/examples/single_write_retention_policy.py +++ b/examples/single_write_retention_policy.py @@ -1,5 +1,6 @@ #!/usr/bin/env python from inflow import Client -client = Client('http://username:pass@localhost:8086/databasename') -client.write('temperature', value=21.3, retention_policy='rp_four_weeks') + +client = Client("http://username:pass@localhost:8086", db="databasename") +client.write("temperature", value=21.3, retention_policy="rp_four_weeks") diff --git a/examples/timeout.py b/examples/timeout.py index a1688bb..279f245 100644 --- a/examples/timeout.py +++ b/examples/timeout.py @@ -2,7 +2,6 @@ from inflow import Client -client = Client('http://username:pass@localhost:8086/databasename', - timeout=0.01) +client = Client("http://username:pass@localhost:8086", db="databasename", timeout=0.01) -client.write('temperature', value=21.3) +client.write("temperature", value=21.3) diff --git a/examples/write_multiple_succinct.py b/examples/write_multiple_succinct.py index 0f085a1..68a74c0 100755 --- a/examples/write_multiple_succinct.py +++ b/examples/write_multiple_succinct.py @@ -2,17 +2,16 @@ from inflow import Client -client = Client('http://username:pass@localhost:8086/databasename') +client = Client("http://username:pass@localhost:8086", db="databasename") temperature = dict( - name='temperature', - tags={ - 'location': 'groningen', - 'sensor_type': 'ni1000' - } + name="temperature", tags={"location": "groningen", "sensor_type": "ni1000"} ) -client.write(temperature, [ - {'value': 21.3, 'timestamp': 1475845863}, - {'value': 20.1, 'timestamp': 1475846182} -]) +client.write( + temperature, + [ + {"value": 21.3, "timestamp": 1475845863}, + {"value": 20.1, "timestamp": 1475846182}, + ], +) diff --git a/examples/write_multiple_values.py b/examples/write_multiple_values.py index 719a706..635f29f 100755 --- a/examples/write_multiple_values.py +++ b/examples/write_multiple_values.py @@ -2,11 +2,6 @@ from inflow import Client -client = Client('http://username:pass@localhost:8086/databasename') +client = Client("http://username:pass@localhost:8086", db="databasename") -client.write( - 'temperature', - timestamp=1475846182, - lower_sensor=20.9, - upper_sensor=23.2 -) +client.write("temperature", timestamp=1475846182, lower_sensor=20.9, upper_sensor=23.2) diff --git a/examples/write_multiple_verbose.py b/examples/write_multiple_verbose.py index 1c5e19b..9375d3e 100755 --- a/examples/write_multiple_verbose.py +++ b/examples/write_multiple_verbose.py @@ -2,25 +2,21 @@ from inflow import Client, Measurement -client = Client('http://username:pass@localhost:8086/databasename') +client = Client("http://username:pass@localhost:8086", db="databasename") -client.write([ - Measurement( - name='temperature', - tags={ - 'location': 'groningen', - 'sensor_type': 'ni1000' - }, - value=21.3, - timestamp=1475845863 - ), - Measurement( - name='temperature', - tags={ - 'location': 'groningen', - 'sensor_type': 'ni1000' - }, - value=20.1, - timestamp=1475848864 - ) -]) +client.write( + [ + Measurement( + name="temperature", + tags={"location": "groningen", "sensor_type": "ni1000"}, + value=21.3, + timestamp=1475845863, + ), + Measurement( + name="temperature", + tags={"location": "groningen", "sensor_type": "ni1000"}, + value=20.1, + timestamp=1475848864, + ), + ] +) diff --git a/inflow/client.py b/inflow/client.py index b3d3aaf..b9f5b49 100644 --- a/inflow/client.py +++ b/inflow/client.py @@ -8,8 +8,8 @@ class Client(WriteMixin): """ The InfluxDB client. """ - def __init__(self, uri, precision='s', retention_policy=None, timeout=None): - self.connection = Connection(uri, precision, retention_policy, timeout) + def __init__(self, uri, db=None, precision='s', retention_policy=None, timeout=None): + self.connection = Connection(uri, db, precision, retention_policy, timeout) def write_func(self, measurement, **kwargs): return self.connection.write(measurement, **kwargs) @@ -17,5 +17,5 @@ def write_func(self, measurement, **kwargs): def session(self, autocommit_every=None, retention_policy=None): return Session(self.connection, autocommit_every, retention_policy) - def query(self, query, epoch=None): - return self.connection.query(query, epoch) + def query(self, query, epoch=None, db=None): + return self.connection.query(query, epoch, db) diff --git a/inflow/connection.py b/inflow/connection.py index 72dd574..a9e5064 100644 --- a/inflow/connection.py +++ b/inflow/connection.py @@ -1,18 +1,22 @@ from requests import post, get from six.moves.urllib.parse import urlparse, quote_plus -from .exceptions import (QueryFailedException, WriteFailedException, - DatabaseNotFoundException, UnauthorizedException, - ForbiddenException) +from .exceptions import ( + QueryFailedException, + WriteFailedException, + DatabaseNotFoundException, + UnauthorizedException, + ForbiddenException, +) -__all__ = ['Connection'] +__all__ = ["Connection"] # All these types of queries should issue a GET request. -GET_QUERIES = ['SELECT', 'SHOW'] +GET_QUERIES = ["SELECT", "SHOW"] def get_method(query): - """ Determines which method should be used to execute this query. + """Determines which method should be used to execute this query. These query types should be issues using a GET: @@ -30,7 +34,7 @@ def get_method(query): * KILL * REVOKE """ - if 'INTO' not in query: + if "INTO" not in query: for word in GET_QUERIES: if word in query: return get @@ -39,31 +43,25 @@ def get_method(query): def parse_query_response(response): - """ Parses the query response and returns a list of response objects. """ + """Parses the query response and returns a list of response objects.""" data = response.json() - if 'results' not in data: + if "results" not in data: return [] retval = [] - series = data['results'][0].get('series', []) + series = data["results"][0].get("series", []) for s in series: - parsed = dict( - name=s['name'], - values=[] - ) + parsed = dict(name=s["name"], values=[]) try: - i = s['columns'].index('time') - s['columns'][i] = 'timestamp' + i = s["columns"].index("time") + s["columns"][i] = "timestamp" except ValueError: pass - for v in s['values']: - parsed['values'].append({ - key: value - for key, value in zip(s['columns'], v) - }) + for v in s["values"]: + parsed["values"].append({key: value for key, value in zip(s["columns"], v)}) retval.append(parsed) @@ -71,82 +69,80 @@ def parse_query_response(response): class Connection: - """ Represents a connection to an InfluxDB instance. """ + """Represents a connection to an InfluxDB instance.""" - def __init__(self, uri, precision='s', retention_policy=None, timeout=None): + def __init__( + self, uri, db=None, precision="s", retention_policy=None, timeout=None + ): parsed = urlparse(uri) - if parsed.hostname is None or\ - parsed.scheme is None: - raise ValueError('Given URI is invalid.') - - if parsed.scheme not in ['http', 'https']: - raise ValueError('Given scheme is not supported, should be ' - 'either http or https, while you specified ' - '{}'.format(parsed.scheme)) + if parsed.hostname is None or parsed.scheme is None: + raise ValueError("Given URI is invalid.") - if parsed.path == '' or parsed.path == '/': - raise ValueError('Should specify a database name.') + if parsed.scheme not in ["http", "https"]: + raise ValueError( + "Given scheme is not supported, should be " + "either http or https, while you specified " + "{}".format(parsed.scheme) + ) - self.uri = '{}://{}'.format( - - parsed.scheme, - parsed.hostname - ) + self.uri = "{}://{}".format(parsed.scheme, parsed.hostname) if parsed.port is not None: - self.uri += ':{}'.format(parsed.port) + self.uri += ":{}".format(parsed.port) - self.auth = ((parsed.username, parsed.password) - if parsed.username is not None - else None) + self.uri += parsed.path - self.db = parsed.path[1:] + self.auth = ( + (parsed.username, parsed.password) if parsed.username is not None else None + ) self.precision = precision + self.db = db self.retention_policy = retention_policy self.timeout = timeout - def get_write_url(self, retention_policy=None): - """ Returns the url needed to write measurements to InfluxDB. """ - url = '{}/write?precision={}&db={}'.format( - self.uri, - self.precision, - self.db + def get_write_url(self, db=None, retention_policy=None): + """Returns the url needed to write measurements to InfluxDB.""" + url = "{}/write?precision={}&db={}".format( + self.uri, self.precision, db if db is not None else self.db ) if retention_policy is not None: - url = '{}&rp={}'.format(url, retention_policy) + url = "{}&rp={}".format(url, retention_policy) elif self.retention_policy is not None: - url = '{}&rp={}'.format(url, self.retention_policy) + url = "{}&rp={}".format(url, self.retention_policy) return url - def get_query_url(self, query, epoch): - """ Returns the url needed to query measurements from InfluxDB. """ - url = '{}/query?db={}&q={}'.format( - self.uri, - self.db, - quote_plus(query) + def get_query_url(self, query, epoch, db=None): + """Returns the url needed to query measurements from InfluxDB.""" + url = "{}/query?db={}&q={}".format( + self.uri, db if db is None else self.db, quote_plus(query) ) if epoch is not None: - if epoch not in ['h', 'm', 's', 'ms', 'u', 'ns']: - raise ValueError('Invalid epoch provided, must be one of ' - 'h, m, s, ms, u or ns.') + if epoch not in ["h", "m", "s", "ms", "u", "ns"]: + raise ValueError( + "Invalid epoch provided, must be one of " "h, m, s, ms, u or ns." + ) - url = '{}&epoch={}'.format(url, epoch) + url = "{}&epoch={}".format(url, epoch) return url - def write(self, measurement, retention_policy=None): - """ Write a single measurement to the InfluxDB API. """ + def write(self, measurement, db=None, retention_policy=None): + """Write a single measurement to the InfluxDB API.""" if type(measurement) is list: - data = '\n'.join([m.to_line(self.precision) for m in measurement]) + data = "\n".join([m.to_line(self.precision) for m in measurement]) else: data = measurement.to_line(self.precision) - rv = post(self.get_write_url(retention_policy), auth=self.auth, - data=data, timeout=self.timeout) + rv = post( + self.get_write_url(db, retention_policy), + auth=self.auth, + data=data, + timeout=self.timeout, + ) if rv.status_code == 400 or rv.status_code == 500: raise WriteFailedException(rv.json()) @@ -157,11 +153,12 @@ def write(self, measurement, retention_policy=None): elif rv.status_code == 404: raise DatabaseNotFoundException(rv.json()) - def query(self, query, epoch=None): - """ Execute a query on InfluxDB. """ + def query(self, query, epoch=None, db=None): + """Execute a query on InfluxDB.""" method = get_method(query) - rv = method(self.get_query_url(query, epoch), auth=self.auth, - timeout=self.timeout) + rv = method( + self.get_query_url(query, epoch, db), auth=self.auth, timeout=self.timeout + ) if rv.status_code == 400: raise QueryFailedException(rv.json()) diff --git a/inflow/write.py b/inflow/write.py index 2e83844..150d571 100644 --- a/inflow/write.py +++ b/inflow/write.py @@ -13,8 +13,12 @@ def write(self, *args, **kwargs): if 'retention_policy' in kwargs: del kwargs['retention_policy'] + db = kwargs.get('db', None) + if 'db' in kwargs: + del kwargs['db'] + if isinstance(first, Measurement): - return self.write_func(first, retention_policy=retention_policy) + return self.write_func(first, retention_policy=retention_policy, db=db) elif type(first) is dict: measurements = [] @@ -24,10 +28,11 @@ def write(self, *args, **kwargs): measurements.append(Measurement(**merge)) return self.write_func(measurements, - retention_policy=retention_policy) + retention_policy=retention_policy, + db=db) elif type(first) is list: - return self.write_func(first, retention_policy=retention_policy) + return self.write_func(first, retention_policy=retention_policy, db=db) elif isinstance(first, six.string_types): return self.write_func( @@ -35,7 +40,8 @@ def write(self, *args, **kwargs): name=first, **kwargs ), - retention_policy=retention_policy + retention_policy=retention_policy, + db=db ) else: raise ValueError('Can\'t create measurements based on the given arguments.') diff --git a/setup.py b/setup.py index a13506b..a7ce180 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( name="inflow", - version="0.3.2", + version="0.4.0b1", author="Jaap Broekhuizen", author_email="broekhuizen@baopt.nl", description="A simple InfluxDB client library.", diff --git a/tests/test_client.py b/tests/test_client.py index 7a08176..5b24e9e 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -1,9 +1,15 @@ import json import pytest from datetime import datetime -from inflow import (Client, Measurement, WriteFailedException, - DatabaseNotFoundException, QueryFailedException, - UnauthorizedException, ForbiddenException) +from inflow import ( + Client, + Measurement, + WriteFailedException, + DatabaseNotFoundException, + QueryFailedException, + UnauthorizedException, + ForbiddenException, +) try: from datetime import timezone @@ -18,7 +24,7 @@ @pytest.fixture def client(): - return Client('https://user:pass@localhost:8086/testdb', timeout=1) + return Client("https://user:pass@localhost:8086", db="testdb", timeout=1) @pytest.fixture @@ -31,192 +37,195 @@ def post(monkeypatch): }] }""") post.return_value = response_mock - monkeypatch.setattr('inflow.connection.post', post) + monkeypatch.setattr("inflow.connection.post", post) return post class TestInit: def test_connection(self): - """ Should be able to pass a http connection URI. """ - client = Client('http://user:pass@localhost:8086/databasename') + """Should be able to pass a http connection URI.""" + client = Client("http://user:pass@localhost:8086", db="databasename") - assert client.connection.auth == ('user', 'pass') - assert client.connection.uri == 'http://localhost:8086' - assert client.connection.db == 'databasename' + assert client.connection.auth == ("user", "pass") + assert client.connection.uri == "http://localhost:8086" + assert client.connection.db == "databasename" def test_no_auth(self): - """ Should be able to parse connection uri without auth. """ - client = Client('http://localhost:8086/databasename') + """Should be able to parse connection uri without auth.""" + client = Client("http://localhost:8086", db="databasename") assert client.connection.auth is None def test_no_port(self): - """ Should be able to not provide a port. """ - client = Client('http://localhost/databasename') - assert client.connection.uri == 'http://localhost' + """Should be able to not provide a port.""" + client = Client("http://localhost", db="databasename") + assert client.connection.uri == "http://localhost" def test_bad_scheme(self): - """ Currently we only support the http and https schemes. """ + """Currently we only support the http and https schemes.""" with pytest.raises(ValueError): - Client('udp://localhost:8086/databasename') - - def test_no_database_name(self): - """ A database name should be specified. """ - with pytest.raises(ValueError): - Client('https://localhost:8086/') + Client("udp://localhost:8086", db="databasename") def test_bad_uri(self): - """ Should throw a ValueError when the given uri is not valid. """ + """Should throw a ValueError when the given uri is not valid.""" with pytest.raises(ValueError): - Client('invalid') + Client("invalid") class TestWrite: def test_simple_measurement(self, client, post): - client.write('temperature', value=21.3, timestamp=1476107241) + client.write("temperature", value=21.3, timestamp=1476107241) post.assert_called_with( - 'https://localhost:8086/write?precision=s&db=testdb', - auth=('user', 'pass'), - data='temperature value=21.3 1476107241', - timeout=1 + "https://localhost:8086/write?precision=s&db=testdb", + auth=("user", "pass"), + data="temperature value=21.3 1476107241", + timeout=1, ) def test_explicit_retention_policy(self, post): - client = Client('https://user:pass@localhost:8086/testdb', - retention_policy='rp_four_weeks', timeout=1) - client.write('temperature', value=21.3, timestamp=1476107241) + client = Client( + "https://user:pass@localhost:8086", + db="testdb", + retention_policy="rp_four_weeks", + timeout=1, + ) + client.write("temperature", value=21.3, timestamp=1476107241) post.assert_called_with( - 'https://localhost:8086/write?precision=s&db=testdb&rp=rp_four_weeks', - auth=('user', 'pass'), - data='temperature value=21.3 1476107241', - timeout=1 + "https://localhost:8086/write?precision=s&db=testdb&rp=rp_four_weeks", + auth=("user", "pass"), + data="temperature value=21.3 1476107241", + timeout=1, ) def test_retention_policy_on_write_call(self, post): - client = Client('https://user:pass@localhost:8086/testdb', timeout=1) - client.write('temperature', value=21.3, timestamp=1476107241, - retention_policy='rp_four_weeks') + client = Client("https://user:pass@localhost:8086", db="testdb", timeout=1) + client.write( + "temperature", + value=21.3, + timestamp=1476107241, + retention_policy="rp_four_weeks", + ) post.assert_called_with( - 'https://localhost:8086/write?precision=s&db=testdb&rp=rp_four_weeks', - auth=('user', 'pass'), - data='temperature value=21.3 1476107241', - timeout=1 + "https://localhost:8086/write?precision=s&db=testdb&rp=rp_four_weeks", + auth=("user", "pass"), + data="temperature value=21.3 1476107241", + timeout=1, ) def test_sorted_tags(self, client, post): - client.write('temperature', tags={'b': 'tag', 'a': 'tag'}, value=21.3, - timestamp=1476107241) + client.write( + "temperature", + tags={"b": "tag", "a": "tag"}, + value=21.3, + timestamp=1476107241, + ) post.assert_called_with( - 'https://localhost:8086/write?precision=s&db=testdb', - auth=('user', 'pass'), - data='temperature,a=tag,b=tag value=21.3 1476107241', - timeout=1 + "https://localhost:8086/write?precision=s&db=testdb", + auth=("user", "pass"), + data="temperature,a=tag,b=tag value=21.3 1476107241", + timeout=1, ) def test_escaped_tags(self, client, post): - client.write('temperature', tags={'a,=b ': 'a,=b '}, value=21.3, - timestamp=1476107241) + client.write( + "temperature", tags={"a,=b ": "a,=b "}, value=21.3, timestamp=1476107241 + ) post.assert_called_with( - 'https://localhost:8086/write?precision=s&db=testdb', - auth=('user', 'pass'), - data='temperature,a\\,\\=b\\ =a\\,\\=b\\ value=21.3 1476107241', - timeout=1 + "https://localhost:8086/write?precision=s&db=testdb", + auth=("user", "pass"), + data="temperature,a\\,\\=b\\ =a\\,\\=b\\ value=21.3 1476107241", + timeout=1, ) def test_escaped_measurements(self, client, post): - client.write('temp er,ature', value=21.3, timestamp=1476107241) + client.write("temp er,ature", value=21.3, timestamp=1476107241) post.assert_called_with( - 'https://localhost:8086/write?precision=s&db=testdb', - auth=('user', 'pass'), - data='temp\\ er\\,ature value=21.3 1476107241', - timeout=1 + "https://localhost:8086/write?precision=s&db=testdb", + auth=("user", "pass"), + data="temp\\ er\\,ature value=21.3 1476107241", + timeout=1, ) def test_escaped_string_values(self, client, post): - client.write('temperature', value='well, a pretty nice "temperature"', - timestamp=1476107241) + client.write( + "temperature", + value='well, a pretty nice "temperature"', + timestamp=1476107241, + ) post.assert_called_with( - 'https://localhost:8086/write?precision=s&db=testdb', - auth=('user', 'pass'), + "https://localhost:8086/write?precision=s&db=testdb", + auth=("user", "pass"), data='temperature value="well, a pretty nice \\"temperature\\"" 1476107241', - timeout=1 + timeout=1, ) def test_measurement_instance(self, client, post): - client.write(Measurement( - 'temperature', - value=21.3, - timestamp=1476107241 - )) + client.write(Measurement("temperature", value=21.3, timestamp=1476107241)) post.assert_called_with( - 'https://localhost:8086/write?precision=s&db=testdb', - auth=('user', 'pass'), - data='temperature value=21.3 1476107241', - timeout=1 + "https://localhost:8086/write?precision=s&db=testdb", + auth=("user", "pass"), + data="temperature value=21.3 1476107241", + timeout=1, ) def test_measurement_no_timestamp(self): - measurement = Measurement( - 'temperature', - value=21.3 - ) + measurement = Measurement("temperature", value=21.3) assert measurement.timestamp def test_measurement_datetime(self, client, post): - client.write(Measurement( - 'temperature', - value=21.3, - timestamp=datetime.fromtimestamp(1476107241, timezone.utc) - )) + client.write( + Measurement( + "temperature", + value=21.3, + timestamp=datetime.fromtimestamp(1476107241, timezone.utc), + ) + ) post.assert_called_with( - 'https://localhost:8086/write?precision=s&db=testdb', - auth=('user', 'pass'), - data='temperature value=21.3 1476107241', - timeout=1 + "https://localhost:8086/write?precision=s&db=testdb", + auth=("user", "pass"), + data="temperature value=21.3 1476107241", + timeout=1, ) def test_measurement_list(self, client, post): - client.write([ - Measurement( - 'temperature', - value=32.1, - timestamp=1476107241 - ), - Measurement( - 'temperature', - value=21.9, - timestamp=1476107319 - ) - ]) + client.write( + [ + Measurement("temperature", value=32.1, timestamp=1476107241), + Measurement("temperature", value=21.9, timestamp=1476107319), + ] + ) post.assert_called_with( - 'https://localhost:8086/write?precision=s&db=testdb', - auth=('user', 'pass'), - data='temperature value=32.1 1476107241\n' - 'temperature value=21.9 1476107319', - timeout=1 + "https://localhost:8086/write?precision=s&db=testdb", + auth=("user", "pass"), + data="temperature value=32.1 1476107241\n" + "temperature value=21.9 1476107319", + timeout=1, ) def test_measurement_template(self, client, post): - temperature = {'name': 'temperature'} + temperature = {"name": "temperature"} - client.write(temperature, [ - {'value': 21.3, 'timestamp': 1476107241}, - {'value': 21.9, 'timestamp': 1476107319} - ]) + client.write( + temperature, + [ + {"value": 21.3, "timestamp": 1476107241}, + {"value": 21.9, "timestamp": 1476107319}, + ], + ) post.assert_called_with( - 'https://localhost:8086/write?precision=s&db=testdb', - auth=('user', 'pass'), - data='temperature value=21.3 1476107241\n' - 'temperature value=21.9 1476107319', - timeout=1 + "https://localhost:8086/write?precision=s&db=testdb", + auth=("user", "pass"), + data="temperature value=21.3 1476107241\n" + "temperature value=21.9 1476107319", + timeout=1, ) def test_measurement_bad_input(self, client): @@ -226,102 +235,107 @@ def test_measurement_bad_input(self, client): @pytest.fixture def post_mock_response(self, post): response_mock = Mock() - response_mock.json.return_value = dict(error='some error') + response_mock.json.return_value = dict(error="some error") post.return_value = response_mock return response_mock - @pytest.mark.parametrize(('status_code', 'exception'), [ - (400, WriteFailedException), - (404, DatabaseNotFoundException), - (500, WriteFailedException), - (401, UnauthorizedException), - (403, ForbiddenException) - ]) - def test_exception(self, client, status_code, exception, post, - post_mock_response): + @pytest.mark.parametrize( + ("status_code", "exception"), + [ + (400, WriteFailedException), + (404, DatabaseNotFoundException), + (500, WriteFailedException), + (401, UnauthorizedException), + (403, ForbiddenException), + ], + ) + def test_exception(self, client, status_code, exception, post, post_mock_response): post_mock_response.status_code = status_code with pytest.raises(exception): - client.write('temperature', value=10) + client.write("temperature", value=10) class TestSession: def test_write_to_session(self, client, post): session = client.session() - session.write('temperature', value=23.1, timestamp=1475848864) - session.write('temperature', value=25.0, timestamp=1475849823) + session.write("temperature", value=23.1, timestamp=1475848864) + session.write("temperature", value=25.0, timestamp=1475849823) session.commit() post.assert_called_with( - 'https://localhost:8086/write?precision=s&db=testdb', - auth=('user', 'pass'), - data='temperature value=23.1 1475848864\n' - 'temperature value=25.0 1475849823', - timeout=1 + "https://localhost:8086/write?precision=s&db=testdb", + auth=("user", "pass"), + data="temperature value=23.1 1475848864\n" + "temperature value=25.0 1475849823", + timeout=1, ) def test_session_as_context_manager(self, client, post): with client.session() as session: - session.write('temperature', value=23.1, timestamp=1475848864) - session.write('temperature', value=25.0, timestamp=1475849823) + session.write("temperature", value=23.1, timestamp=1475848864) + session.write("temperature", value=25.0, timestamp=1475849823) post.assert_called_with( - 'https://localhost:8086/write?precision=s&db=testdb', - auth=('user', 'pass'), - data='temperature value=23.1 1475848864\n' - 'temperature value=25.0 1475849823', - timeout=1 + "https://localhost:8086/write?precision=s&db=testdb", + auth=("user", "pass"), + data="temperature value=23.1 1475848864\n" + "temperature value=25.0 1475849823", + timeout=1, ) def test_session_autocommit_every(self, client, post): session = client.session(autocommit_every=5) - session.write('temperature', value=23.1, timestamp=1475848864) - session.write('temperature', value=25.0, timestamp=1475849823) - session.write('temperature', value=22.9, timestamp=1475849825) - session.write('temperature', value=28.2, timestamp=1475849912) + session.write("temperature", value=23.1, timestamp=1475848864) + session.write("temperature", value=25.0, timestamp=1475849823) + session.write("temperature", value=22.9, timestamp=1475849825) + session.write("temperature", value=28.2, timestamp=1475849912) post.assert_not_called() # This next write call will trigger the autocommit. - session.write('temperature', value=25.1, timestamp=1475849999) + session.write("temperature", value=25.1, timestamp=1475849999) post.assert_called_with( - 'https://localhost:8086/write?precision=s&db=testdb', - auth=('user', 'pass'), - data='temperature value=23.1 1475848864\n' - 'temperature value=25.0 1475849823\n' - 'temperature value=22.9 1475849825\n' - 'temperature value=28.2 1475849912\n' - 'temperature value=25.1 1475849999', - timeout=1 + "https://localhost:8086/write?precision=s&db=testdb", + auth=("user", "pass"), + data="temperature value=23.1 1475848864\n" + "temperature value=25.0 1475849823\n" + "temperature value=22.9 1475849825\n" + "temperature value=28.2 1475849912\n" + "temperature value=25.1 1475849999", + timeout=1, ) def test_session_autocommit_every_list(self, client, post): session = client.session(autocommit_every=5) - temperature = {'name': 'temperature'} + temperature = {"name": "temperature"} - session.write(temperature, [ - {'name': 'temperature', 'value': 23.1, 'timestamp': 1475848864}, - {'name': 'temperature', 'value': 25.0, 'timestamp': 1475849823}, - {'name': 'temperature', 'value': 22.9, 'timestamp': 1475849825}, - {'name': 'temperature', 'value': 28.2, 'timestamp': 1475849912}, - {'name': 'temperature', 'value': 25.1, 'timestamp': 1475849999}, - {'name': 'temperature', 'value': 29.3, 'timestamp': 1475859999} - ]) + session.write( + temperature, + [ + {"name": "temperature", "value": 23.1, "timestamp": 1475848864}, + {"name": "temperature", "value": 25.0, "timestamp": 1475849823}, + {"name": "temperature", "value": 22.9, "timestamp": 1475849825}, + {"name": "temperature", "value": 28.2, "timestamp": 1475849912}, + {"name": "temperature", "value": 25.1, "timestamp": 1475849999}, + {"name": "temperature", "value": 29.3, "timestamp": 1475859999}, + ], + ) post.assert_called_with( - 'https://localhost:8086/write?precision=s&db=testdb', - auth=('user', 'pass'), - data='temperature value=23.1 1475848864\n' - 'temperature value=25.0 1475849823\n' - 'temperature value=22.9 1475849825\n' - 'temperature value=28.2 1475849912\n' - 'temperature value=25.1 1475849999\n' - 'temperature value=29.3 1475859999', - timeout=1 + "https://localhost:8086/write?precision=s&db=testdb", + auth=("user", "pass"), + data="temperature value=23.1 1475848864\n" + "temperature value=25.0 1475849823\n" + "temperature value=22.9 1475849825\n" + "temperature value=28.2 1475849912\n" + "temperature value=25.1 1475849999\n" + "temperature value=29.3 1475859999", + timeout=1, ) @@ -342,13 +356,13 @@ def get(monkeypatch): }] }""") get.return_value = response_mock - monkeypatch.setattr('inflow.connection.get', get) + monkeypatch.setattr("inflow.connection.get", get) return get class TestQuery: def test_get_measurements(self, client, get): - """ Should be able to parse resulting measurements into a nice list of + """Should be able to parse resulting measurements into a nice list of dicts. InfluxDB returns this: @@ -387,49 +401,51 @@ def test_get_measurements(self, client, get): ] """ rv = client.query('SELECT * FROM "temperatures"') - assert rv[0]['name'] == 'temperatures' - assert rv[0]['values'][0] == { + assert rv[0]["name"] == "temperatures" + assert rv[0]["values"][0] == { "timestamp": "2016-01-01T00:01:00Z", "value": 20.1, - "location": "groningen" + "location": "groningen", } - @pytest.mark.parametrize('query', [ - 'SELECT * FROM "temperatures"', - 'SHOW FIELD KEYS from "temperatures"' - ]) + @pytest.mark.parametrize( + "query", ['SELECT * FROM "temperatures"', 'SHOW FIELD KEYS from "temperatures"'] + ) def test_should_call_get(self, client, query, get, post): - """ Should use GET for these queries. """ + """Should use GET for these queries.""" client.query(query) assert get.called - @pytest.mark.parametrize('query', [ - 'SELECT mean(value) as value INTO "temperature_averages" FROM "temperatures"', - 'ALTER RETENTION POLICY "rp_four_weeks" DEFAULT', - 'CREATE DATABASE "new_db"', - 'DELETE FROM "temperatures"', - 'DROP DATABASE "new_db"', - 'GRANT ALL TO "user"', - 'KILL QUERY 36', - 'REVOKE ALL PRIVILEGES FROM "user"' - ]) + @pytest.mark.parametrize( + "query", + [ + 'SELECT mean(value) as value INTO "temperature_averages" FROM "temperatures"', + 'ALTER RETENTION POLICY "rp_four_weeks" DEFAULT', + 'CREATE DATABASE "new_db"', + 'DELETE FROM "temperatures"', + 'DROP DATABASE "new_db"', + 'GRANT ALL TO "user"', + "KILL QUERY 36", + 'REVOKE ALL PRIVILEGES FROM "user"', + ], + ) def test_should_call_post(self, client, query, post, get): - """ Should use POST for these queries. """ + """Should use POST for these queries.""" client.query(query) assert post.called def test_should_use_epoch_on_query(self, client, get): - client.query('SELECT * FROM "temperature"', epoch='s') + client.query('SELECT * FROM "temperature"', epoch="s") # If get is not called, get.call_args is None assert get.call_args is not None url = get.call_args[0][0] - assert 'epoch=s' in url + assert "epoch=s" in url def test_should_throw_on_invalid_epoch(self, client, get): with pytest.raises(ValueError): - client.query('SELECT * FROM "temperature"', epoch='not an epoch') + client.query('SELECT * FROM "temperature"', epoch="not an epoch") def test_should_quote_query(self, client, get): client.query('SELECT * FROM "temperatures"') @@ -438,24 +454,26 @@ def test_should_quote_query(self, client, get): assert get.call_args is not None url = get.call_args[0][0] - assert 'SELECT+%2A+FROM+%22temperatures%22' in url + assert "SELECT+%2A+FROM+%22temperatures%22" in url @pytest.fixture def get_mock_response(self, get): response_mock = Mock() - response_mock.json.return_value = dict(error='some error') + response_mock.json.return_value = dict(error="some error") get.return_value = response_mock return response_mock - @pytest.mark.parametrize(('status_code', 'exception'), [ - (400, QueryFailedException), - (401, UnauthorizedException), - (403, ForbiddenException) - ]) - def test_exception(self, client, status_code, exception, get, - get_mock_response): + @pytest.mark.parametrize( + ("status_code", "exception"), + [ + (400, QueryFailedException), + (401, UnauthorizedException), + (403, ForbiddenException), + ], + ) + def test_exception(self, client, status_code, exception, get, get_mock_response): get_mock_response.status_code = status_code with pytest.raises(exception) as exc: - client.query('SELECT * FROM measurements') + client.query("SELECT * FROM measurements") assert exc.value.message == {"error": "some error"}