Skip to content
This repository was archived by the owner on Oct 29, 2024. It is now read-only.

Use GET & POST appropriately according to InfluxDB documentation #608

Merged
merged 2 commits into from
Jul 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Finally add a CHANGELOG.md to communicate breaking changes (#598)
- Test multiple versions of InfluxDB in travis
### Changed
- Update POST/GET requests to follow verb guidelines from InfluxDB documentation
- Update test suite to support InfluxDB v1.3.9, v1.4.2, and v1.5.4
- Fix performance degradation when removing NaN values via line protocol (#592)
### Removed
Expand Down
2 changes: 1 addition & 1 deletion examples/tutorial_sine_wave.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def main(host='localhost', port=8086):
time.sleep(3)

query = 'SELECT * FROM foobar'
print("Queying data: " + query)
print("Querying data: " + query)
result = client.query(query, database=DBNAME)
print("Result: {0}".format(result))

Expand Down
44 changes: 27 additions & 17 deletions influxdb/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,8 @@ def query(self,
database=None,
raise_errors=True,
chunked=False,
chunk_size=0):
chunk_size=0,
method="GET"):
"""Send a query to InfluxDB.

:param query: the actual query string
Expand Down Expand Up @@ -384,6 +385,9 @@ def query(self,
:param chunk_size: Size of each chunk to tell InfluxDB to use.
:type chunk_size: int

:param method: the HTTP method for the request, defaults to GET
:type method: str

:returns: the queried data
:rtype: :class:`~.ResultSet`
"""
Expand All @@ -401,9 +405,12 @@ def query(self,
if chunk_size > 0:
params['chunk_size'] = chunk_size

if query.lower().startswith("select ") and " into " in query.lower():
method = "POST"

response = self.request(
url="query",
method='GET',
method=method,
params=params,
data=None,
expected_response_code=expected_response_code
Expand Down Expand Up @@ -568,15 +575,17 @@ def create_database(self, dbname):
:param dbname: the name of the database to create
:type dbname: str
"""
self.query("CREATE DATABASE {0}".format(quote_ident(dbname)))
self.query("CREATE DATABASE {0}".format(quote_ident(dbname)),
method="POST")

def drop_database(self, dbname):
"""Drop a database from InfluxDB.

:param dbname: the name of the database to drop
:type dbname: str
"""
self.query("DROP DATABASE {0}".format(quote_ident(dbname)))
self.query("DROP DATABASE {0}".format(quote_ident(dbname)),
method="POST")

def get_list_measurements(self):
"""Get the list of measurements in InfluxDB.
Expand All @@ -602,7 +611,8 @@ def drop_measurement(self, measurement):
:param measurement: the name of the measurement to drop
:type measurement: str
"""
self.query("DROP MEASUREMENT {0}".format(quote_ident(measurement)))
self.query("DROP MEASUREMENT {0}".format(quote_ident(measurement)),
method="POST")

def create_retention_policy(self, name, duration, replication,
database=None, default=False):
Expand Down Expand Up @@ -634,11 +644,11 @@ def create_retention_policy(self, name, duration, replication,
if default is True:
query_string += " DEFAULT"

self.query(query_string)
self.query(query_string, method="POST")

def alter_retention_policy(self, name, database=None,
duration=None, replication=None, default=None):
"""Mofidy an existing retention policy for a database.
"""Modify an existing retention policy for a database.

:param name: the name of the retention policy to modify
:type name: str
Expand Down Expand Up @@ -671,7 +681,7 @@ def alter_retention_policy(self, name, database=None,
if default is True:
query_string += " DEFAULT"

self.query(query_string)
self.query(query_string, method="POST")

def drop_retention_policy(self, name, database=None):
"""Drop an existing retention policy for a database.
Expand All @@ -685,7 +695,7 @@ def drop_retention_policy(self, name, database=None):
query_string = (
"DROP RETENTION POLICY {0} ON {1}"
).format(quote_ident(name), quote_ident(database or self._database))
self.query(query_string)
self.query(query_string, method="POST")

def get_list_retention_policies(self, database=None):
"""Get the list of retention policies for a database.
Expand Down Expand Up @@ -751,16 +761,16 @@ def create_user(self, username, password, admin=False):
quote_ident(username), quote_literal(password))
if admin:
text += ' WITH ALL PRIVILEGES'
self.query(text)
self.query(text, method="POST")

def drop_user(self, username):
"""Drop a user from InfluxDB.

:param username: the username to drop
:type username: str
"""
text = "DROP USER {0}".format(quote_ident(username))
self.query(text)
text = "DROP USER {0}".format(quote_ident(username), method="POST")
self.query(text, method="POST")

def set_user_password(self, username, password):
"""Change the password of an existing user.
Expand Down Expand Up @@ -796,7 +806,7 @@ def delete_series(self, database=None, measurement=None, tags=None):
tag_eq_list = ["{0}={1}".format(quote_ident(k), quote_literal(v))
for k, v in tags.items()]
query_str += ' WHERE ' + ' AND '.join(tag_eq_list)
self.query(query_str, database=database)
self.query(query_str, database=database, method="POST")

def grant_admin_privileges(self, username):
"""Grant cluster administration privileges to a user.
Expand All @@ -808,7 +818,7 @@ def grant_admin_privileges(self, username):
and manage users.
"""
text = "GRANT ALL PRIVILEGES TO {0}".format(quote_ident(username))
self.query(text)
self.query(text, method="POST")

def revoke_admin_privileges(self, username):
"""Revoke cluster administration privileges from a user.
Expand All @@ -820,7 +830,7 @@ def revoke_admin_privileges(self, username):
and manage users.
"""
text = "REVOKE ALL PRIVILEGES FROM {0}".format(quote_ident(username))
self.query(text)
self.query(text, method="POST")

def grant_privilege(self, privilege, database, username):
"""Grant a privilege on a database to a user.
Expand All @@ -836,7 +846,7 @@ def grant_privilege(self, privilege, database, username):
text = "GRANT {0} ON {1} TO {2}".format(privilege,
quote_ident(database),
quote_ident(username))
self.query(text)
self.query(text, method="POST")

def revoke_privilege(self, privilege, database, username):
"""Revoke a privilege on a database from a user.
Expand All @@ -852,7 +862,7 @@ def revoke_privilege(self, privilege, database, username):
text = "REVOKE {0} ON {1} FROM {2}".format(privilege,
quote_ident(database),
quote_ident(username))
self.query(text)
self.query(text, method="POST")

def get_list_privileges(self, username):
"""Get the list of all privileges granted to given user.
Expand Down
49 changes: 36 additions & 13 deletions influxdb/tests/client_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,29 @@ def test_query(self):
[{'value': 0.64, 'time': '2009-11-10T23:00:00Z'}]
)

def test_select_into_post(self):
"""Test SELECT.*INTO is POSTed."""
example_response = (
'{"results": [{"series": [{"measurement": "sdfsdfsdf", '
'"columns": ["time", "value"], "values": '
'[["2009-11-10T23:00:00Z", 0.64]]}]}, {"series": '
'[{"measurement": "cpu_load_short", "columns": ["time", "value"], '
'"values": [["2009-11-10T23:00:00Z", 0.64]]}]}]}'
)

with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.POST,
"http://localhost:8086/query",
text=example_response
)
rs = self.cli.query('select * INTO newmeas from foo')

self.assertListEqual(
list(rs[0].get_points()),
[{'value': 0.64, 'time': '2009-11-10T23:00:00Z'}]
)

@unittest.skip('Not implemented for 0.9')
def test_query_chunked(self):
"""Test chunked query for TestInfluxDBClient object."""
Expand Down Expand Up @@ -495,7 +518,7 @@ def test_create_database(self):
"""Test create database for TestInfluxDBClient object."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.GET,
requests_mock.POST,
"http://localhost:8086/query",
text='{"results":[{}]}'
)
Expand All @@ -509,7 +532,7 @@ def test_create_numeric_named_database(self):
"""Test create db w/numeric name for TestInfluxDBClient object."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.GET,
requests_mock.POST,
"http://localhost:8086/query",
text='{"results":[{}]}'
)
Expand All @@ -529,7 +552,7 @@ def test_drop_database(self):
"""Test drop database for TestInfluxDBClient object."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.GET,
requests_mock.POST,
"http://localhost:8086/query",
text='{"results":[{}]}'
)
Expand All @@ -543,7 +566,7 @@ def test_drop_measurement(self):
"""Test drop measurement for TestInfluxDBClient object."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.GET,
requests_mock.POST,
"http://localhost:8086/query",
text='{"results":[{}]}'
)
Expand All @@ -557,7 +580,7 @@ def test_drop_numeric_named_database(self):
"""Test drop numeric db for TestInfluxDBClient object."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.GET,
requests_mock.POST,
"http://localhost:8086/query",
text='{"results":[{}]}'
)
Expand Down Expand Up @@ -615,7 +638,7 @@ def test_create_retention_policy_default(self):

with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.GET,
requests_mock.POST,
"http://localhost:8086/query",
text=example_response
)
Expand All @@ -635,7 +658,7 @@ def test_create_retention_policy(self):

with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.GET,
requests_mock.POST,
"http://localhost:8086/query",
text=example_response
)
Expand All @@ -655,7 +678,7 @@ def test_alter_retention_policy(self):

with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.GET,
requests_mock.POST,
"http://localhost:8086/query",
text=example_response
)
Expand Down Expand Up @@ -695,7 +718,7 @@ def test_drop_retention_policy(self):

with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.GET,
requests_mock.POST,
"http://localhost:8086/query",
text=example_response
)
Expand Down Expand Up @@ -879,7 +902,7 @@ def test_grant_admin_privileges(self):

with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.GET,
requests_mock.POST,
"http://localhost:8086/query",
text=example_response
)
Expand All @@ -903,7 +926,7 @@ def test_revoke_admin_privileges(self):

with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.GET,
requests_mock.POST,
"http://localhost:8086/query",
text=example_response
)
Expand All @@ -927,7 +950,7 @@ def test_grant_privilege(self):

with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.GET,
requests_mock.POST,
"http://localhost:8086/query",
text=example_response
)
Expand All @@ -951,7 +974,7 @@ def test_revoke_privilege(self):

with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.GET,
requests_mock.POST,
"http://localhost:8086/query",
text=example_response
)
Expand Down
20 changes: 19 additions & 1 deletion influxdb/tests/server_tests/client_test_with_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ def test_drop_user(self):
self.assertEqual(users, [])

def test_drop_user_nonexisting(self):
"""Test dropping a nonexistant user."""
"""Test dropping a nonexistent user."""
with self.assertRaises(InfluxDBClientError) as ctx:
self.cli.drop_user('test')
self.assertIn('user not found',
Expand Down Expand Up @@ -383,6 +383,24 @@ def test_write_multiple_points_different_series(self):
]]
)

def test_select_into_as_post(self):
"""Test SELECT INTO is POSTed."""
self.assertIs(True, self.cli.write_points(dummy_points))
time.sleep(1)
rsp = self.cli.query('SELECT * INTO "newmeas" FROM "memory"')
rsp = self.cli.query('SELECT * FROM "newmeas"')
lrsp = list(rsp)

self.assertEqual(
lrsp,
[[
{'value': 33,
'time': '2009-11-10T23:01:35Z',
"host": "server01",
"region": "us-west"}
]]
)

@unittest.skip("Broken as of 0.9.0")
def test_write_multiple_points_different_series_DF(self):
"""Test write multiple points using dataframe to different series."""
Expand Down