Skip to content

Commit b7d75af

Browse files
authored
Use GET & POST appropriately according to InfluxDB documentation (influxdata#608)
* Use GET & POST appropriately according to InfluxDB documentation From 'https://docs.influxdata.com/influxdb/v1.5/tools/api/#verb-usage', certain queries should be POST (where previously they have been GET) * Appease flake8
1 parent a47c801 commit b7d75af

File tree

5 files changed

+84
-32
lines changed

5 files changed

+84
-32
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
99
- Finally add a CHANGELOG.md to communicate breaking changes (#598)
1010
- Test multiple versions of InfluxDB in travis
1111
### Changed
12+
- Update POST/GET requests to follow verb guidelines from InfluxDB documentation
1213
- Update test suite to support InfluxDB v1.3.9, v1.4.2, and v1.5.4
1314
- Fix performance degradation when removing NaN values via line protocol (#592)
1415
### Removed

examples/tutorial_sine_wave.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def main(host='localhost', port=8086):
4343
time.sleep(3)
4444

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

influxdb/client.py

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,8 @@ def query(self,
350350
database=None,
351351
raise_errors=True,
352352
chunked=False,
353-
chunk_size=0):
353+
chunk_size=0,
354+
method="GET"):
354355
"""Send a query to InfluxDB.
355356
356357
:param query: the actual query string
@@ -384,6 +385,9 @@ def query(self,
384385
:param chunk_size: Size of each chunk to tell InfluxDB to use.
385386
:type chunk_size: int
386387
388+
:param method: the HTTP method for the request, defaults to GET
389+
:type method: str
390+
387391
:returns: the queried data
388392
:rtype: :class:`~.ResultSet`
389393
"""
@@ -401,9 +405,12 @@ def query(self,
401405
if chunk_size > 0:
402406
params['chunk_size'] = chunk_size
403407

408+
if query.lower().startswith("select ") and " into " in query.lower():
409+
method = "POST"
410+
404411
response = self.request(
405412
url="query",
406-
method='GET',
413+
method=method,
407414
params=params,
408415
data=None,
409416
expected_response_code=expected_response_code
@@ -568,15 +575,17 @@ def create_database(self, dbname):
568575
:param dbname: the name of the database to create
569576
:type dbname: str
570577
"""
571-
self.query("CREATE DATABASE {0}".format(quote_ident(dbname)))
578+
self.query("CREATE DATABASE {0}".format(quote_ident(dbname)),
579+
method="POST")
572580

573581
def drop_database(self, dbname):
574582
"""Drop a database from InfluxDB.
575583
576584
:param dbname: the name of the database to drop
577585
:type dbname: str
578586
"""
579-
self.query("DROP DATABASE {0}".format(quote_ident(dbname)))
587+
self.query("DROP DATABASE {0}".format(quote_ident(dbname)),
588+
method="POST")
580589

581590
def get_list_measurements(self):
582591
"""Get the list of measurements in InfluxDB.
@@ -602,7 +611,8 @@ def drop_measurement(self, measurement):
602611
:param measurement: the name of the measurement to drop
603612
:type measurement: str
604613
"""
605-
self.query("DROP MEASUREMENT {0}".format(quote_ident(measurement)))
614+
self.query("DROP MEASUREMENT {0}".format(quote_ident(measurement)),
615+
method="POST")
606616

607617
def create_retention_policy(self, name, duration, replication,
608618
database=None, default=False):
@@ -634,11 +644,11 @@ def create_retention_policy(self, name, duration, replication,
634644
if default is True:
635645
query_string += " DEFAULT"
636646

637-
self.query(query_string)
647+
self.query(query_string, method="POST")
638648

639649
def alter_retention_policy(self, name, database=None,
640650
duration=None, replication=None, default=None):
641-
"""Mofidy an existing retention policy for a database.
651+
"""Modify an existing retention policy for a database.
642652
643653
:param name: the name of the retention policy to modify
644654
:type name: str
@@ -671,7 +681,7 @@ def alter_retention_policy(self, name, database=None,
671681
if default is True:
672682
query_string += " DEFAULT"
673683

674-
self.query(query_string)
684+
self.query(query_string, method="POST")
675685

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

690700
def get_list_retention_policies(self, database=None):
691701
"""Get the list of retention policies for a database.
@@ -751,16 +761,16 @@ def create_user(self, username, password, admin=False):
751761
quote_ident(username), quote_literal(password))
752762
if admin:
753763
text += ' WITH ALL PRIVILEGES'
754-
self.query(text)
764+
self.query(text, method="POST")
755765

756766
def drop_user(self, username):
757767
"""Drop a user from InfluxDB.
758768
759769
:param username: the username to drop
760770
:type username: str
761771
"""
762-
text = "DROP USER {0}".format(quote_ident(username))
763-
self.query(text)
772+
text = "DROP USER {0}".format(quote_ident(username), method="POST")
773+
self.query(text, method="POST")
764774

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

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

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

825835
def grant_privilege(self, privilege, database, username):
826836
"""Grant a privilege on a database to a user.
@@ -836,7 +846,7 @@ def grant_privilege(self, privilege, database, username):
836846
text = "GRANT {0} ON {1} TO {2}".format(privilege,
837847
quote_ident(database),
838848
quote_ident(username))
839-
self.query(text)
849+
self.query(text, method="POST")
840850

841851
def revoke_privilege(self, privilege, database, username):
842852
"""Revoke a privilege on a database from a user.
@@ -852,7 +862,7 @@ def revoke_privilege(self, privilege, database, username):
852862
text = "REVOKE {0} ON {1} FROM {2}".format(privilege,
853863
quote_ident(database),
854864
quote_ident(username))
855-
self.query(text)
865+
self.query(text, method="POST")
856866

857867
def get_list_privileges(self, username):
858868
"""Get the list of all privileges granted to given user.

influxdb/tests/client_test.py

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,29 @@ def test_query(self):
439439
[{'value': 0.64, 'time': '2009-11-10T23:00:00Z'}]
440440
)
441441

442+
def test_select_into_post(self):
443+
"""Test SELECT.*INTO is POSTed."""
444+
example_response = (
445+
'{"results": [{"series": [{"measurement": "sdfsdfsdf", '
446+
'"columns": ["time", "value"], "values": '
447+
'[["2009-11-10T23:00:00Z", 0.64]]}]}, {"series": '
448+
'[{"measurement": "cpu_load_short", "columns": ["time", "value"], '
449+
'"values": [["2009-11-10T23:00:00Z", 0.64]]}]}]}'
450+
)
451+
452+
with requests_mock.Mocker() as m:
453+
m.register_uri(
454+
requests_mock.POST,
455+
"http://localhost:8086/query",
456+
text=example_response
457+
)
458+
rs = self.cli.query('select * INTO newmeas from foo')
459+
460+
self.assertListEqual(
461+
list(rs[0].get_points()),
462+
[{'value': 0.64, 'time': '2009-11-10T23:00:00Z'}]
463+
)
464+
442465
@unittest.skip('Not implemented for 0.9')
443466
def test_query_chunked(self):
444467
"""Test chunked query for TestInfluxDBClient object."""
@@ -495,7 +518,7 @@ def test_create_database(self):
495518
"""Test create database for TestInfluxDBClient object."""
496519
with requests_mock.Mocker() as m:
497520
m.register_uri(
498-
requests_mock.GET,
521+
requests_mock.POST,
499522
"http://localhost:8086/query",
500523
text='{"results":[{}]}'
501524
)
@@ -509,7 +532,7 @@ def test_create_numeric_named_database(self):
509532
"""Test create db w/numeric name for TestInfluxDBClient object."""
510533
with requests_mock.Mocker() as m:
511534
m.register_uri(
512-
requests_mock.GET,
535+
requests_mock.POST,
513536
"http://localhost:8086/query",
514537
text='{"results":[{}]}'
515538
)
@@ -529,7 +552,7 @@ def test_drop_database(self):
529552
"""Test drop database for TestInfluxDBClient object."""
530553
with requests_mock.Mocker() as m:
531554
m.register_uri(
532-
requests_mock.GET,
555+
requests_mock.POST,
533556
"http://localhost:8086/query",
534557
text='{"results":[{}]}'
535558
)
@@ -543,7 +566,7 @@ def test_drop_measurement(self):
543566
"""Test drop measurement for TestInfluxDBClient object."""
544567
with requests_mock.Mocker() as m:
545568
m.register_uri(
546-
requests_mock.GET,
569+
requests_mock.POST,
547570
"http://localhost:8086/query",
548571
text='{"results":[{}]}'
549572
)
@@ -557,7 +580,7 @@ def test_drop_numeric_named_database(self):
557580
"""Test drop numeric db for TestInfluxDBClient object."""
558581
with requests_mock.Mocker() as m:
559582
m.register_uri(
560-
requests_mock.GET,
583+
requests_mock.POST,
561584
"http://localhost:8086/query",
562585
text='{"results":[{}]}'
563586
)
@@ -615,7 +638,7 @@ def test_create_retention_policy_default(self):
615638

616639
with requests_mock.Mocker() as m:
617640
m.register_uri(
618-
requests_mock.GET,
641+
requests_mock.POST,
619642
"http://localhost:8086/query",
620643
text=example_response
621644
)
@@ -635,7 +658,7 @@ def test_create_retention_policy(self):
635658

636659
with requests_mock.Mocker() as m:
637660
m.register_uri(
638-
requests_mock.GET,
661+
requests_mock.POST,
639662
"http://localhost:8086/query",
640663
text=example_response
641664
)
@@ -655,7 +678,7 @@ def test_alter_retention_policy(self):
655678

656679
with requests_mock.Mocker() as m:
657680
m.register_uri(
658-
requests_mock.GET,
681+
requests_mock.POST,
659682
"http://localhost:8086/query",
660683
text=example_response
661684
)
@@ -695,7 +718,7 @@ def test_drop_retention_policy(self):
695718

696719
with requests_mock.Mocker() as m:
697720
m.register_uri(
698-
requests_mock.GET,
721+
requests_mock.POST,
699722
"http://localhost:8086/query",
700723
text=example_response
701724
)
@@ -879,7 +902,7 @@ def test_grant_admin_privileges(self):
879902

880903
with requests_mock.Mocker() as m:
881904
m.register_uri(
882-
requests_mock.GET,
905+
requests_mock.POST,
883906
"http://localhost:8086/query",
884907
text=example_response
885908
)
@@ -903,7 +926,7 @@ def test_revoke_admin_privileges(self):
903926

904927
with requests_mock.Mocker() as m:
905928
m.register_uri(
906-
requests_mock.GET,
929+
requests_mock.POST,
907930
"http://localhost:8086/query",
908931
text=example_response
909932
)
@@ -927,7 +950,7 @@ def test_grant_privilege(self):
927950

928951
with requests_mock.Mocker() as m:
929952
m.register_uri(
930-
requests_mock.GET,
953+
requests_mock.POST,
931954
"http://localhost:8086/query",
932955
text=example_response
933956
)
@@ -951,7 +974,7 @@ def test_revoke_privilege(self):
951974

952975
with requests_mock.Mocker() as m:
953976
m.register_uri(
954-
requests_mock.GET,
977+
requests_mock.POST,
955978
"http://localhost:8086/query",
956979
text=example_response
957980
)

influxdb/tests/server_tests/client_test_with_server.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ def test_drop_user(self):
211211
self.assertEqual(users, [])
212212

213213
def test_drop_user_nonexisting(self):
214-
"""Test dropping a nonexistant user."""
214+
"""Test dropping a nonexistent user."""
215215
with self.assertRaises(InfluxDBClientError) as ctx:
216216
self.cli.drop_user('test')
217217
self.assertIn('user not found',
@@ -383,6 +383,24 @@ def test_write_multiple_points_different_series(self):
383383
]]
384384
)
385385

386+
def test_select_into_as_post(self):
387+
"""Test SELECT INTO is POSTed."""
388+
self.assertIs(True, self.cli.write_points(dummy_points))
389+
time.sleep(1)
390+
rsp = self.cli.query('SELECT * INTO "newmeas" FROM "memory"')
391+
rsp = self.cli.query('SELECT * FROM "newmeas"')
392+
lrsp = list(rsp)
393+
394+
self.assertEqual(
395+
lrsp,
396+
[[
397+
{'value': 33,
398+
'time': '2009-11-10T23:01:35Z',
399+
"host": "server01",
400+
"region": "us-west"}
401+
]]
402+
)
403+
386404
@unittest.skip("Broken as of 0.9.0")
387405
def test_write_multiple_points_different_series_DF(self):
388406
"""Test write multiple points using dataframe to different series."""

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy