summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack <jack@db.2.localnet.cc>2015-07-04 12:37:58 +0000
committerJack <jack@db.2.localnet.cc>2015-07-04 17:57:35 +0000
commit8aefb69293cd37bf81c178ab8102db980e6f46a3 (patch)
treef2f9540f587dad60e467229e68cec6342b098362
downloadpyinflux-8aefb69293cd37bf81c178ab8102db980e6f46a3.tar.gz
pyinflux-8aefb69293cd37bf81c178ab8102db980e6f46a3.zip
0.1
-rw-r--r--.gitignore1
-rw-r--r--pyinfluxtools/__init__.py143
-rw-r--r--setup.py24
3 files changed, 168 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..72723e5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*pyc
diff --git a/pyinfluxtools/__init__.py b/pyinfluxtools/__init__.py
new file mode 100644
index 0000000..74ec19a
--- /dev/null
+++ b/pyinfluxtools/__init__.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python3
+import re
+
+
+class WriteRequest(object):
+ @staticmethod
+ def parse(lines):
+ """
+ Parse multiple Write objects separeted by new-line character.
+
+ >>> lines = []
+ >>> lines += ['cpu']
+ >>> lines += ['cpu,host=serverA,region=us-west']
+ >>> lines += ['cpu,host=serverA,region=us-west field1=1,field2=2']
+ >>> lines += ['cpu,host=serverA,region=us-west field1=1,field2=2 1234']
+ >>> print("\\n".join(map(str, WriteRequest.parse("\\n".join(lines)))))
+ cpu
+ cpu,host=serverA,region=us-west
+ cpu,host=serverA,region=us-west field1=1,field2=2
+ cpu,host=serverA,region=us-west field1=1,field2=2 1234
+ """
+ writes = map(Write.parse, lines.split("\n"))
+ return list(writes)
+
+ @staticmethod
+ def parseFile(file):
+ for line in file.readlines():
+ yield Write.parse(line)
+
+
+class Write(object):
+ def __init__(self, key, tags, fields, timestamp):
+ self.key = key
+ self.tags = tags
+ self.fields = fields
+ self.timestamp = timestamp
+
+ @staticmethod
+ def parse(line):
+ """
+ Parse a line from the POST request into a Write object.
+
+ >>> Write.parse('cpu')
+ <Write key=cpu tags=None fields=None timestamp=None>
+ >>> print(Write.parse('cpu'))
+ cpu
+
+ >>> Write.parse('cpu,host=serverA,region=us-west')
+ <Write key=cpu tags=[('host', 'serverA'), ('region', 'us-west')] fields=None timestamp=None>
+ >>> print(Write.parse('cpu,host=serverA,region=us-west'))
+ cpu,host=serverA,region=us-west
+
+ >>> Write.parse('cpu\\,01,host=serverA,region=us-west')
+ <Write key=cpu,01 tags=[('host', 'serverA'), ('region', 'us-west')] fields=None timestamp=None>
+ >>> print(Write.parse('cpu\,01,host=serverA,region=us-west'))
+ cpu\,01,host=serverA,region=us-west
+
+ >>> Write.parse('cpu,host=server\\ A,region=us\\ west')
+ <Write key=cpu tags=[('host', 'server A'), ('region', 'us west')] fields=None timestamp=None>
+ >>> print(Write.parse('cpu,host=server\\ A,region=us\\ west'))
+ cpu,host=server\ A,region=us\ west
+
+ >>> Write.parse('cpu,ho\=st=server\ A,region=us\ west')
+ <Write key=cpu tags=[('ho=st', 'server A'), ('region', 'us west')] fields=None timestamp=None>
+ >>> print(Write.parse('cpu,ho\=st=server\ A,region=us\ west'))
+ cpu,ho\=st=server\ A,region=us\ west
+
+ >>> print(Write.parse('cpu,ho\=st=server\ A field=123'))
+ cpu,ho\=st=server\ A field=123
+ >>> print(Write.parse('cpu,foo=bar,foo=bar field=123,field=123')) # error: double name is accepted
+ cpu,foo=bar,foo=bar field=123,field=123
+ >>> print(Write.parse('cpu field12=12'))
+ cpu field12=12
+ >>> print(Write.parse('cpu field12=12 123123123'))
+ cpu field12=12 123123123
+ >>> print(Write.parse('cpu field12=12 1231abcdef123'))
+ Traceback (most recent call last):
+ ...
+ ValueError: invalid literal for int() with base 10: '1231abcdef123'
+ """
+ def unescape(string):
+ return re.sub(r'(?<!\\)([\\,=])', '', string)
+
+ args = re.split(r"(?<!\\) ", line)
+ key, *tags = re.split(r"(?<!\\),", args[0])
+ key = unescape(key)
+
+ if tags:
+ tags = map(lambda tag: re.split(r"(?<!\\)=", tag), tags)
+ tags = map(lambda tag: (unescape(tag[0]), unescape(tag[1])), tags)
+ tags = list(tags)
+ else:
+ tags = None
+
+ if len(args) > 1:
+ fields = re.split(r"(?<!\\),", args[1])
+ fields = map(lambda field: re.split(r"(?<!\\)=", field), fields)
+ fields = map(lambda field: (unescape(field[0]), unescape(field[1])), fields)
+ fields = list(fields)
+ else:
+ fields = None
+
+ if len(args) > 2:
+ timestamp = int(args[2])
+ else:
+ timestamp = None
+
+ return Write(key, tags, fields, timestamp)
+
+ def __repr__(self):
+ return "<{} key={} tags={} fields={} timestamp={}>".format(
+ self.__class__.__name__, self.key, self.tags, self.fields, self.timestamp)
+
+ def __str__(self):
+ def escape(string):
+ return re.sub(r'([\\,= ])', '\\\\\\1', string)
+
+ def escape_kv(kvlist):
+ return ",".join(
+ map(lambda kv: escape(kv[0]) + "=" + escape(kv[1]),
+ kvlist))
+
+ result = escape(self.key)
+
+ if self.tags:
+ result += ","
+ result += escape_kv(self.tags)
+
+ if self.fields:
+ result += " "
+ result += escape_kv(self.fields)
+
+ if self.timestamp:
+ result += " "
+ result += str(self.timestamp)
+
+ return result
+
+
+if __name__ == "__main__":
+ import doctest
+ doctest.testmod()
+
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000..a82b3c6
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+
+from distutils.core import setup
+
+setup(name='pyinfluxtools',
+ version='0.1',
+ description='Python classes to work with influxdb',
+ author='Yves Fischer',
+ author_email='yvesf+github@xapek.org',
+ license="MIT",
+ packages = ['pyinfluxtools'],
+# url='https://github.com/',
+# scripts=[],
+# install_requires=[],
+ classifiers = [
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 3",
+ "Development Status :: 3 - Alpha",
+ "Intended Audience :: Developers",
+ "Operating System :: OS Independent",
+ "License :: OSI Approved :: MIT License",
+ ]
+)
+