{ "info": { "author": "Michael Elsdorfer", "author_email": "michael@elsdoerfer.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3.6", "Topic :: Database" ], "description": "influx-sansio\n=============\n\nPython client for InfluxDB following the `SansIO`_ principle.\n\nInfluxDB is an open-source distributed time series database. Find more\nabout InfluxDB at http://influxdata.com/\n\n\nInstallation\n------------\n\nTo install the latest release:\n\n.. code:: bash\n\n $ pip install influx-sansio\n\nThe library is still in beta, so you may also want to install the latest version from\nthe development branch:\n\n.. code:: bash\n\n $ pip install git+https://github.com/miracle2k/influx-sansio@dev\n\n\nDependencies\n~~~~~~~~~~~~\n\nThe library supports Python 3.5+.\n\nThere is one optional third-party library dependency: \n|pandas|_ for (optional) ``DataFrame`` reading/writing support.\n\nFor the concrete IO implementations, there are aditional dependencies.\n\n.. |pandas| replace:: ``pandas``\n.. _pandas: https://github.com/pandas-dev/pandas\n.. _`SansIO`: https://sans-io.readthedocs.io/\n\n\n\nUsage\n-----\n\nThe module has these parts:\n\n- Low-level utilities that implement generating and parsing the InfluxDB \n line protocol (for writing data), and some helpers for generating queries.\n\n This is Sans-IO, and you can use this to implement your own client.\n\n- An abstract base class that provides a easy to use `client` interface,\n which lets you do `client.query()` or `client.write()` calls.\n\n- Concrete implementations of this base class for various IO backends,\n currently the `asks` library which supports both `trio` and `curio`.\n\n\nSans-IO (low-level utilities)\n~~~~~~~~~~~\n\nSee the modules `influx_sansio.serialization` and `influx_sansio.http`.\n\n\nClient\n~~~~~~\n\n\n\n.. code:: python\n\n import asyncio\n import trio\n from influx_sansio.asks import InfluxDBClient\n\n point = dict(time='2009-11-10T23:00:00Z',\n measurement='cpu_load_short',\n tags={'host': 'server01',\n 'region': 'us-west'},\n fields={'value': 0.64})\n\n client = InfluxDBClient(db='testdb')\n\n coros = [client.create_database(db='testdb'),\n client.write(point),\n client.query('SELECT value FROM cpu_load_short')]\n\n loop = asyncio.get_event_loop()\n results = loop.run_until_complete(asyncio.gather(*coros))\n for result in results:\n print(result)\n\n\nWriting data\n~~~~~~~~~~~~\n\nInput data can be:\n\n1. A string properly formatted in InfluxDB's line protocol\n2. A dictionary containing the following keys: ``measurement``, ``time``, ``tags``, ``fields``\n3. A Pandas ``DataFrame`` with a ``DatetimeIndex``\n4. An iterable of one of the above\n\nInput data in formats 2-4 are parsed into the `line protocol`_ before being written to InfluxDB.\nBeware that serialization is not highly optimized (cythonization PRs are welcome!) and may become\na bottleneck depending on your application.\n\nThe ``write`` method returns ``True`` when successful and raises an\n``InfluxDBError`` otherwise.\n\n.. _`line protocol`: https://docs.influxdata.com/influxdb/latest/write_protocols/line_protocol_reference/\n\n\nWriting dictionary-like objects\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nWe accept any dictionary-like object (mapping) as input.\nHowever, that dictionary must be properly formatted and contain the\nfollowing keys:\n\n1) **measurement**: Optional. Must be a string-like object. If\n omitted, must be specified when calling ``InfluxDBClient.write``\n by passing a ``measurement`` argument.\n2) **time**: Optional. The value can be ``datetime.datetime``,\n date-like string (e.g., ``2017-01-01``, ``2009-11-10T23:00:00Z``) or\n anything else that can be parsed by Pandas' |Timestamp|_ class initializer.\n3) **tags**: Optional. This must contain another mapping of field\n names and values. Both tag keys and values should be strings.\n4) **fields**: Mandatory. This must contain another mapping of field\n names and values. Field keys should be strings. Field values can be\n ``float``, ``int``, ``str``, or ``bool`` or any equivalent type (e.g. Numpy types).\n\n.. |Timestamp| replace:: ``Timestamp``\n.. _Timestamp: https://pandas.pydata.org/pandas-docs/stable/timeseries.html\n\n\nAny fields other then the above will be ignored when writing data to\nInfluxDB.\n\nA typical dictionary-like point would look something like the following:\n\n.. code:: python\n\n {'time': '2009-11-10T23:00:00Z',\n 'measurement': 'cpu_load_short',\n 'tags': {'host': 'server01', 'region': 'us-west'},\n 'fields': {'value1': 0.64, 'value2': True, 'value3': 10}}\n\n\nWriting DataFrames\n^^^^^^^^^^^^^^^^^^\n\nWe also accept Pandas dataframes as input. The only requirements\nfor the dataframe is that the index **must** be of type\n``DatetimeIndex``. Also, any column whose ``dtype`` is ``object`` will\nbe converted to a string representation.\n\nA typical dataframe input should look something like the following:\n\n.. code:: text\n\n LUY BEM AJW tag\n 2017-06-24 08:45:17.929097+00:00 2.545409 5.173134 5.532397 B\n 2017-06-24 10:15:17.929097+00:00 -0.306673 -1.132941 -2.130625 E\n 2017-06-24 11:45:17.929097+00:00 0.894738 -0.561979 -1.487940 B\n 2017-06-24 13:15:17.929097+00:00 -1.799512 -1.722805 -2.308823 D\n 2017-06-24 14:45:17.929097+00:00 0.390137 -0.016709 -0.667895 E\n\nThe measurement name must be specified with the ``measurement`` argument\nwhen calling ``InfluxDBClient.write``. Additional tags can also be\npassed using arbitrary keyword arguments.\n\n**Example:**\n\n.. code:: python\n\n client = InfluxDBClient(db='testdb')\n client.write(df, measurement='prices', tag_columns=['tag'], asset_class='equities')\n\nIn the example above, ``df`` is the dataframe we are trying to write to\nInfluxDB and ``measurement`` is the measurement we are writing to.\n\n``tag_columns`` is in an optional iterable telling which of the\ndataframe columns should be parsed as tag values. If ``tag_columns`` is\nnot explicitly passed, all columns in the dataframe will be treated as\nInfluxDB field values.\n\nAny other keyword arguments passed to ``InfluxDBClient.write`` are\ntreated as extra tags which will be attached to the data being written\nto InfluxDB. Any string which is a valid `InfluxDB identifier`_ and\nvalid `Python identifier`_ can be used as an extra tag key (with the\nexception of they strings ``data``, ``measurement`` and ``tag_columns``).\n\nSee ``InfluxDBClient.write`` docstring for details.\n\n.. _`InfluxDB identifier`: https://docs.influxdata.com/influxdb/latest/query_language/spec/#identifiers\n.. _`Python identifier`: https://docs.python.org/3/reference/lexical_analysis.html#identifiers\n\n\nQuerying data\n~~~~~~~~~~~~~\n\nQuerying data is as simple as passing an InfluxDB query string to\n``InfluxDBClient.query``:\n\n.. code:: python\n\n client.query('SELECT myfield FROM mymeasurement')\n\nThe result (in ``blocking`` and ``async`` modes) is a dictionary\ncontaining the parsed JSON data returned by the InfluxDB `HTTP API`_:\n\n.. _`HTTP API`: https://docs.influxdata.com/influxdb/latest/guides/querying_data/#querying-data-using-the-http-api\n\n.. code:: python\n\n {'results': [{'series': [{'columns': ['time', 'Price', 'Volume'],\n 'name': 'mymeasurement',\n 'values': [[1491963424224703000, 5783, 100],\n [1491963424375146000, 5783, 200],\n [1491963428374895000, 5783, 100],\n [1491963429645478000, 5783, 1100],\n [1491963429655289000, 5783, 100],\n [1491963437084443000, 5783, 100],\n [1491963442274656000, 5783, 900],\n [1491963442274657000, 5782, 5500],\n [1491963442274658000, 5781, 3200],\n [1491963442314710000, 5782, 100]]}],\n 'statement_id': 0}]}\n\n\nRetrieving DataFrames\n^^^^^^^^^^^^^^^^^^^^^\n\nWhen the client is in ``dataframe`` mode, ``InfluxDBClient.query`` will\nreturn a Pandas ``DataFrame``:\n\n\n.. code:: text\n\n Price Volume\n 2017-04-12 02:17:04.224703+00:00 5783 100\n 2017-04-12 02:17:04.375146+00:00 5783 200\n 2017-04-12 02:17:08.374895+00:00 5783 100\n 2017-04-12 02:17:09.645478+00:00 5783 1100\n 2017-04-12 02:17:09.655289+00:00 5783 100\n 2017-04-12 02:17:17.084443+00:00 5783 100\n 2017-04-12 02:17:22.274656+00:00 5783 900\n 2017-04-12 02:17:22.274657+00:00 5782 5500\n 2017-04-12 02:17:22.274658+00:00 5781 3200\n 2017-04-12 02:17:22.314710+00:00 5782 100\n\nMode can be chosen not only during object instantiation but also by\nsimply |changing_mode|_.\n\n\n.. |changing_mode| replace:: changing the ``mode`` attribute\n.. _changing_mode: #switching-modes\n\n\nChunked responses\n^^^^^^^^^^^^^^^^^\n\nThe library supports InfluxDB chunked queries. Passing ``chunked=True`` when calling\n``InfluxDBClient.query``, returns an AsyncGenerator object, which can asynchronously\niterated. Using chunked requests allows response processing to be partially done before\nthe full response is retrieved, reducing overall query time.\n\n.. code:: python\n\n chunks = await client.query(\"SELECT * FROM mymeasurement\", chunked=True)\n async for chunk in chunks:\n # do something\n await process_chunk(...)\n\n\nFor Python 3.5, this relies on the async_generator (https://github.com/python-trio/async_generator)\nlibrary.\n\n\nIterating responses\n^^^^^^^^^^^^^^^^^^^\n\n``InfluxDBClient.query`` returns a parsed JSON response from InfluxDB. In order to easily \niterate over that JSON response point by point, we provide the ``iter_resp`` generator:\n\n.. code:: python\n\n from influx_sansio import iter_resp\n\n r = client.query('SELECT * from h2o_quality LIMIT 10')\n for i in iter_resp(r):\n print(i)\n\n.. code:: text\n\n [1439856000000000000, 41, 'coyote_creek', '1']\n [1439856000000000000, 99, 'santa_monica', '2']\n [1439856360000000000, 11, 'coyote_creek', '3']\n [1439856360000000000, 56, 'santa_monica', '2']\n [1439856720000000000, 65, 'santa_monica', '3']\n\n``iter_resp`` can also be used with chunked responses:\n\n.. code:: python\n\n chunks = await client.query('SELECT * from h2o_quality', chunked=True)\n async for chunk in chunks:\n for point in iter_resp(chunk):\n # do something\n\nBy default, ``iter_resp`` yields a plain list of values without doing any expensive parsing.\nHowever, in case a specific format is needed, an optional ``parser`` argument can be passed.\n``parser`` is a function that takes the raw value list for each data point and an additional\nmetadata dictionary containing all or a subset of the following:\n``{'columns', 'name', 'tags', 'statement_id'}``.\n\n\n.. code:: python\n\n r = await client.query('SELECT * from h2o_quality LIMIT 5')\n for i in iter_resp(r, lambda x, meta: dict(zip(meta['columns'], x))):\n print(i)\n\n.. code:: text\n\n {'time': 1439856000000000000, 'index': 41, 'location': 'coyote_creek', 'randtag': '1'}\n {'time': 1439856000000000000, 'index': 99, 'location': 'santa_monica', 'randtag': '2'}\n {'time': 1439856360000000000, 'index': 11, 'location': 'coyote_creek', 'randtag': '3'}\n {'time': 1439856360000000000, 'index': 56, 'location': 'santa_monica', 'randtag': '2'}\n {'time': 1439856720000000000, 'index': 65, 'location': 'santa_monica', 'randtag': '3'}\n\n\nQuery patterns\n^^^^^^^^^^^^^^\n\nThe library provides a wrapping mechanism around ``InfluxDBClient.query`` in\norder to provide convenient access to commonly used query patterns.\n\nQuery patterns are query strings containing optional named \"replacement fields\"\nsurrounded by curly braces ``{}``, just as in |str_format|_.\nReplacement field values are defined by keyword arguments when calling the method\nassociated with the query pattern. Differently from plain |str_format|, positional\narguments are also supported and can be mixed with keyword arguments.\n\nBuilt-in query patterns are defined on the class.\nUsers can also dynamically define additional query patterns by using\nthe |set_qp|_ helper function.\nUser-defined query patterns have the disadvantage of not being shown for\nauto-completion in IDEs such as Pycharm.\nHowever, they do show up in dynamic environments such as Jupyter.\nIf you have a query pattern that you think will used by many people and should be built-in,\nplease submit a PR.\n\nBuilt-in query pattern examples:\n\n.. code:: python\n\n client.create_database(db='foo') # CREATE DATABASE {db}\n client.drop_measurement('bar') # DROP MEASUREMENT {measurement}'\n client.show_users() # SHOW USERS\n\n # Positional and keyword arguments can be mixed\n client.show_tag_values_from('bar', key='spam') # SHOW TAG VALUES FROM {measurement} WITH key = \"{key}\"\n\nPlease refer to InfluxDB documentation_ for further query-related information.\n\n.. _documentation: https://docs.influxdata.com/influxdb/latest/query_language/\n.. |str_format| replace:: ``str_format()``\n.. _str_format: https://docs.python.org/3/library/string.html#formatstrings\n\n\nOther functionality\n~~~~~~~~~~~~~~~~~~~\n\nAuthentication\n^^^^^^^^^^^^^^\n\nThe library supports basic HTTP authenticatio. Simply pass ``username`` and ``password`` \nwhen instantiating ``InfluxDBClient``:\n\n.. code:: python\n\n client = InfluxDBClient(username='user', password='pass)\n\n\nUnix domain sockets\n^^^^^^^^^^^^^^^^^^^\n\nIf your InfluxDB server uses UNIX domain sockets you can use ``unix_socket``\nwhen instantiating ``InfluxDBClient``:\n\n.. code:: python\n\n client = InfluxDBClient(unix_socket='/path/to/socket')\n\n\nHTTPS/SSL\n^^^^^^^^^\n\nThe library uses HTTP by default, but HTTPS can be used by passing ``ssl=True``\nwhen instantiating ``InfluxDBClient``:\n\n\n.. code:: python\n\n client = InfluxDBClient(host='my.host.io', ssl=True)\n\n\nDatabase selection\n^^^^^^^^^^^^^^^^^^\n\nAfter the instantiation of the ``InfluxDBClient`` object, database\ncan be switched by changing the ``db`` attribute:\n\n.. code:: python\n\n client = InfluxDBClient(db='db1')\n client.db = 'db2'\n\nBeware that differently from some NoSQL databases (such as MongoDB),\nInfluxDB requires that a databases is explicitly created (by using the\n|CREATE_DATABASE|_ query) before doing any operations on it.\n\n.. |CREATE_DATABASE| replace:: ``CREATE DATABASE``\n.. _`CREATE_DATABASE`: https://docs.influxdata.com/influxdb/latest/query_language/database_management/#create-database\n\n\nImplementation\n--------------\n\nSince InfluxDB exposes all its functionality through an `HTTP\nAPI `__,\n``InfluxDBClient`` tries to be nothing more than a thin and simple\nwrapper around that API.\n\nThe InfluxDB HTTP API exposes exactly three endpoints/functions:\n``ping``, ``write`` and ``query``.\n\n``InfluxDBClient`` merely wraps these three functions and provides\nsome parsing functionality for generating line protocol data (when\nwriting) and parsing JSON responses (when querying).\n\nAdditionally,\n`partials `__ are\nused in order to provide convenient access to commonly used query\npatterns. See the `Query patterns <#query-patterns>`__\nsection for details.\n\n\nCredits\n-------\n\nForked from `aioinflux `_.\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/miracle2k/influx-sansio", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "influx-sansio", "package_url": "https://pypi.org/project/influx-sansio/", "platform": "", "project_url": "https://pypi.org/project/influx-sansio/", "project_urls": { "Homepage": "https://github.com/miracle2k/influx-sansio" }, "release_url": "https://pypi.org/project/influx-sansio/0.1.1/", "requires_dist": null, "requires_python": "", "summary": "SansIO Python client for InfluxDB", "version": "0.1.1" }, "last_serial": 4220303, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "774615322eee2d9434aec6ab36de4839", "sha256": "05bdb24af1340d2c70d9bce58f6bd086e2b78c8f22e7e7ec1e9efa8ad07fab4c" }, "downloads": -1, "filename": "influx-sansio-0.1.0.tar.gz", "has_sig": false, "md5_digest": "774615322eee2d9434aec6ab36de4839", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6", "size": 14041, "upload_time": "2018-03-21T18:26:54", "url": "https://files.pythonhosted.org/packages/aa/7f/efa5d7899f6d1bc01cd8c1bc68f3e95e307189e7414b8b955417b40e56b0/influx-sansio-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "65de65def59b18d7bd0fcd41795c48c9", "sha256": "5c9428fe0ea6153a13908b4eb1ce061057105f8e5725c971b0bdfc14ed022963" }, "downloads": -1, "filename": "influx-sansio-0.1.1.tar.gz", "has_sig": false, "md5_digest": "65de65def59b18d7bd0fcd41795c48c9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18788, "upload_time": "2018-08-29T20:37:33", "url": "https://files.pythonhosted.org/packages/8a/aa/79220b1c31692b7e1f52ad34b5319c3fe804b47da521b89641d39e05079c/influx-sansio-0.1.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "65de65def59b18d7bd0fcd41795c48c9", "sha256": "5c9428fe0ea6153a13908b4eb1ce061057105f8e5725c971b0bdfc14ed022963" }, "downloads": -1, "filename": "influx-sansio-0.1.1.tar.gz", "has_sig": false, "md5_digest": "65de65def59b18d7bd0fcd41795c48c9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18788, "upload_time": "2018-08-29T20:37:33", "url": "https://files.pythonhosted.org/packages/8a/aa/79220b1c31692b7e1f52ad34b5319c3fe804b47da521b89641d39e05079c/influx-sansio-0.1.1.tar.gz" } ] }