# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['examples', 'taos', 'taosrest', 'tests']

package_data = \
{'': ['*']}

install_requires = \
['iso8601==1.0.2', 'pytz']

extras_require = \
{'ws:python_version >= "3.7" and python_version < "4.0"': ['taos-ws-py>=0.2.0']}

entry_points = \
{'sqlalchemy.dialects': ['taos = taos.sqlalchemy:TaosDialect',
                         'taosrest = taosrest.sqlalchemy:TaosRestDialect',
                         'taosws = taos.sqlalchemy:TaosWsDialect']}

setup_kwargs = {
    'name': 'taospy',
    'version': '2.7.1',
    'description': 'TDengine connector for python',
    'long_description': '# TDengine Connector for Python\n[![codecov](https://codecov.io/gh/taosdata/taos-connector-python/branch/main/graph/badge.svg?token=BDANN3DBXS)](https://codecov.io/gh/taosdata/taos-connector-python)\n\n[TDengine](https://github.com/taosdata/TDengine) connector for Python enables python programs to access TDengine, using an API which is compliant with the Python DB API 2.0 (PEP-249). It contains two modules:\n\n1. The `taos` module. It uses TDengine C client library for client server communications.\n2. The `taosrest` module. It wraps TDengine RESTful API to Python DB API 2.0 (PEP-249). With this module, you are free to install TDengine C client library.\n\n## Install\n\nYou can use `pip` to install the connector from PyPI:\n\n```bash\npip install taospy\n```\n\nOr with git url:\n\n```bash\npip install git+https://github.com/taosdata/taos-connector-python.git\n```\n\n## Source Code\n\n[TDengine](https://github.com/taosdata/TDengine) connector for Python source code is hosted on [GitHub](https://github.com/taosdata/taos-connector-python).\n\n## Examples for `taosws` Module\n\n### Query with PEP-249 API using `taosws`\n\n```python\nimport taosws\n\n# all parameters are optional\nconn = taosws.connect("taosws://root:taosdata@localhost:6041")\ncursor = conn.cursor()\n\ncursor.execute("show databases")\nresults: list[tuple] = cursor.fetchall()\nfor row in results:\n    print(row)\n```\n\n### Query with query method using `taosws`\n\n```python\nfrom taosws import *\n\nconn = connect("taosws://root:taosdata@localhost:6041")\nresult = conn.query("show databases")\n\nnum_of_fields = result.field_count\nfor field in result.fields:\n    print(field)\n\nfor row in result:\n    print(row)\n```\n\n### Read with Pandas using `taosws`\n\n#### Method one\n\n```python\nimport pandas\nimport taosws\n\nconn = taosws.connect("taosws://root:taosdata@localhost:6041")\ndf: pandas.DataFrame = pandas.read_sql("show databases", conn)\ndf\n```\n\n#### Method Two\n\n```python\nimport pandas\nfrom sqlalchemy import create_engine\n\nengine = create_engine("taosws://root:taosdata@localhost:6041")\ndf: pandas.DataFrame = pandas.read_sql("show databases", engine)\ndf\n```\n\n## Examples for `taosrest` Module\n\n### Query with PEP-249 API\n\n```python\nimport taosrest\n\n# all parameters are optional\nconn = taosrest.connect(url="http://localhost:6041",\n                        user="root",\n                        password="taosdata")\ncursor = conn.cursor()\n\ncursor.execute("show databases")\nresults: list[tuple] = cursor.fetchall()\nfor row in results:\n    print(row)\n```\n\n### Query with query method\n\n```python\nfrom taosrest import connect, TaosRestConnection, Result\n\nconn: TaosRestConnection = connect()\nresult: Result = conn.query("show databases")\n\nnum_of_fields = result.field_count\nfor field in result.fields:\n    print(field)\n\nfor row in result:\n    print(row)\n```\n\n### Read with Pandas\n\n#### Method one\n\n```python\nimport pandas\nimport taos\n\nconn = taos.connect()\ndf: pandas.DataFrame = pandas.read_sql("select * from log.logs", conn)\n```\n\n#### Method two\n\n```python\nimport pandas\nimport taosrest\n\nconn = taosrest.connect()\ndf: pandas.DataFrame = pandas.read_sql("select * from log.logs", conn)\n```\n\n#### Method three\n\n```python\nimport pandas\nfrom sqlalchemy import create_engine\n\nengine = create_engine("taosrest://root:taosdata@localhost:6041")\ndf: pandas.DataFrame = pandas.read_sql("select * from log.logs", engine)\n```\n\n## Examples for `taos` Module\n\n### Connect options\n\nSupported config options:\n\n- **config**: TDengine client configuration directory, by default use "/etc/taos/".\n- **host**: TDengine server host, by default use "localhost".\n- **user**: TDengine user name, default is "root".\n- **password**: TDengine user password, default is "taosdata".\n- **database**: Default connection database name, empty if not set.\n- **timezone**: Timezone for timestamp type (which is `datetime` object with tzinfo in python) no matter what the host\'s timezone is.\n\n```python\nimport taos\n\n# 1. with empty options, connect TDengine by default options\n#   that means:\n#     - use /etc/taos/taos.cfg as default configuration file\n#     - use "localhost" if not set in config file\n#     - use "root" as default username\n#     - use "taosdata" as default password\n#     - use 6030 as default port if not set in config file\n#     - use local timezone datetime as timestamp\nconn = taos.connect()\n# 2. with full set options, default db: log, use UTC datetime.\nconn = taos.connect(host=\'localhost\',\n                    user=\'root\',\n                    password=\'taosdata\',\n                    database=\'log\',\n                    config=\'/etc/taos\',\n                    timezone=\'UTC\')\n```\n\nNote that, the datetime formatted string will contain timezone information when timezone set. For example:\n\n```python\n# without timezone(local timezone depends on your machine)\n\'1969-12-31 16:00:00\'\n# with timezone UTC\n\'1969-12-31 16:00:00+00:00\'\n```\n\n### Query with PEP-249 API\n\n```python\nimport taos\n\nconn = taos.connect()\ncursor = conn.cursor()\n\ncursor.execute("show databases")\nresults = cursor.fetchall()\nfor row in results:\n    print(row)\n\ncursor.close()\nconn.close()\n```\n\n### Query with objective API\n\n```python\nimport taos\n\nconn = taos.connect()\nconn.execute("create database if not exists pytest")\n\nresult = conn.query("show databases")\nnum_of_fields = result.field_count\nfor field in result.fields:\n    print(field)\n\nfor row in result:\n    print(row)\n\nresult.close()\nconn.execute("drop database pytest")\nconn.close()\n```\n\n### Query with async API\n\n```python\nfrom taos import *\nfrom ctypes import *\nimport time\n\n\ndef fetch_callback(p_param, p_result, num_of_rows):\n    print("fetched ", num_of_rows, "rows")\n    p = cast(p_param, POINTER(Counter))\n    result = TaosResult(p_result)\n\n    if num_of_rows == 0:\n        print("fetching completed")\n        p.contents.done = True\n        result.close()\n        return\n\n    if num_of_rows < 0:\n        p.contents.done = True\n        result.check_error(num_of_rows)\n        result.close()\n        return None\n\n    for row in result.rows_iter(num_of_rows):\n        # print(row)\n        None\n\n    p.contents.count += result.row_count\n    result.fetch_rows_a(fetch_callback, p_param)\n\n\ndef query_callback(p_param, p_result, code):\n    # type: (c_void_p, c_void_p, c_int) -> None\n    if p_result is None:\n        return\n\n    result = TaosResult(p_result)\n    if code == 0:\n        result.fetch_rows_a(fetch_callback, p_param)\n\n    result.check_error(code)\n\n\nclass Counter(Structure):\n    _fields_ = [("count", c_int), ("done", c_bool)]\n\n    def __str__(self):\n        return "{ count: %d, done: %s }" % (self.count, self.done)\n\n\ndef test_query(conn):\n    # type: (TaosConnection) -> None\n    counter = Counter(count=0)\n    conn.query_a("select * from log.log", query_callback, byref(counter))\n\n    while not counter.done:\n        print("wait query callback")\n        time.sleep(1)\n\n    print(counter)\n    conn.close()\n\n\nif __name__ == "__main__":\n    test_query(connect())\n```\n\n### Statement API - Bind row after row\n\n```python\nfrom taos import *\n\nconn = connect()\n\ndbname = "pytest_taos_stmt"\nconn.execute("drop database if exists %s" % dbname)\nconn.execute("create database if not exists %s" % dbname)\nconn.select_db(dbname)\n\nconn.execute(\n    "create table if not exists log(ts timestamp, bo bool, nil tinyint, \\\n        ti tinyint, si smallint, ii int, bi bigint, tu tinyint unsigned, \\\n        su smallint unsigned, iu int unsigned, bu bigint unsigned, \\\n        ff float, dd double, bb binary(100), nn nchar(100), tt timestamp)",\n)\n\nstmt = conn.statement("insert into log values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")\n\nparams = new_bind_params(16)\nparams[0].timestamp(1626861392589)\nparams[1].bool(True)\nparams[2].tinyint(None)\nparams[3].tinyint(2)\nparams[4].smallint(3)\nparams[5].int(4)\nparams[6].bigint(5)\nparams[7].tinyint_unsigned(6)\nparams[8].smallint_unsigned(7)\nparams[9].int_unsigned(8)\nparams[10].bigint_unsigned(9)\nparams[11].float(10.1)\nparams[12].double(10.11)\nparams[13].binary("hello")\nparams[14].nchar("stmt")\nparams[15].timestamp(1626861392589)\nstmt.bind_param(params)\n\nparams[0].timestamp(1626861392590)\nparams[15].timestamp(None)\nstmt.bind_param(params)\nstmt.execute()\n\nassert stmt.affected_rows == 2\n\nresult = conn.query("select * from log")\n\nfor row in result:\n    print(row)\n```\n\n### Statement API - Bind multi rows\n\n```python\nfrom taos import *\n\nconn = connect()\n\ndbname = "pytest_taos_stmt"\nconn.execute("drop database if exists %s" % dbname)\nconn.execute("create database if not exists %s" % dbname)\nconn.select_db(dbname)\n\nconn.execute(\n    "create table if not exists log(ts timestamp, bo bool, nil tinyint, \\\n        ti tinyint, si smallint, ii int, bi bigint, tu tinyint unsigned, \\\n        su smallint unsigned, iu int unsigned, bu bigint unsigned, \\\n        ff float, dd double, bb binary(100), nn nchar(100), tt timestamp)",\n)\n\nstmt = conn.statement("insert into log values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")\n\nparams = new_multi_binds(16)\nparams[0].timestamp((1626861392589, 1626861392590, 1626861392591))\nparams[1].bool((True, None, False))\nparams[2].tinyint([-128, -128, None])  # -128 is tinyint null\nparams[3].tinyint([0, 127, None])\nparams[4].smallint([3, None, 2])\nparams[5].int([3, 4, None])\nparams[6].bigint([3, 4, None])\nparams[7].tinyint_unsigned([3, 4, None])\nparams[8].smallint_unsigned([3, 4, None])\nparams[9].int_unsigned([3, 4, None])\nparams[10].bigint_unsigned([3, 4, None])\nparams[11].float([3, None, 1])\nparams[12].double([3, None, 1.2])\nparams[13].binary(["abc", "dddafadfadfadfadfa", None])\nparams[14].nchar(["涛思数据", None, "a long string with 中文字符"])\nparams[15].timestamp([None, None, 1626861392591])\nstmt.bind_param_batch(params)\nstmt.execute()\n\nassert stmt.affected_rows == 3\n\nresult = conn.query("select * from log")\nfor row in result:\n    print(row)\n```\n\n### Subscription\n\n```python\nimport taos\nimport random\n\nconn = taos.connect()\ndbname = "pytest_taos_subscribe"\nconn.execute("drop database if exists %s" % dbname)\nconn.execute("create database if not exists %s" % dbname)\nconn.select_db(dbname)\nconn.execute("create table if not exists log(ts timestamp, n int)")\nfor i in range(10):\n    conn.execute("insert into log values(now, %d)" % i)\n\nsub = conn.subscribe(False, "test", "select * from log", 1000)\nprint("# consume from begin")\nfor ts, n in sub.consume():\n    print(ts, n)\n\nprint("# consume new data")\nfor i in range(5):\n    conn.execute("insert into log values(now, %d)(now+1s, %d)" % (i, i))\n    result = sub.consume()\n    for ts, n in result:\n        print(ts, n)\n\nsub.close(True)\nprint("# keep progress consume")\nsub = conn.subscribe(False, "test", "select * from log", 1000)\nresult = sub.consume()\nrows = result.fetch_all()\n# consume from latest subscription needs root privilege(for /var/lib/taos).\nassert result.row_count == 0\nprint("## consumed ", len(rows), "rows")\n\nprint("# consume with a stop condition")\nfor i in range(10):\n    conn.execute("insert into log values(now, %d)" % random.randint(0, 10))\n    result = sub.consume()\n    try:\n        ts, n = next(result)\n        print(ts, n)\n        if n > 5:\n            result.stop_query()\n            print("## stopped")\n            break\n    except StopIteration:\n        continue\n\nsub.close()\n# sub.close()\n\nconn.execute("drop database if exists %s" % dbname)\n# conn.close()\n```\n\n### Subscription asynchronously with callback\n\n```python\nfrom taos import *\nfrom ctypes import *\n\nimport time\n\n\ndef subscribe_callback(p_sub, p_result, p_param, errno):\n    # type: (c_void_p, c_void_p, c_void_p, c_int) -> None\n    print("# fetch in callback")\n    result = TaosResult(c_void_p(p_result))\n    result.check_error(errno)\n    for row in result.rows_iter():\n        ts, n = row()\n        print(ts, n)\n\n\ndef test_subscribe_callback(conn):\n    # type: (TaosConnection) -> None\n    dbname = "pytest_taos_subscribe_callback"\n    try:\n        print("drop if exists")\n        conn.execute("drop database if exists %s" % dbname)\n        print("create database")\n        conn.execute("create database if not exists %s" % dbname)\n        print("create table")\n        # conn.execute("use %s" % dbname)\n        conn.execute("create table if not exists %s.log(ts timestamp, n int)" % dbname)\n\n        print("# subscribe with callback")\n        sub = conn.subscribe(False, "test", "select * from %s.log" % dbname, 1000, subscribe_callback)\n\n        for i in range(10):\n            conn.execute("insert into %s.log values(now, %d)" % (dbname, i))\n            time.sleep(0.7)\n\n        sub.close()\n\n        conn.execute("drop database if exists %s" % dbname)\n        # conn.close()\n    except Exception as err:\n        conn.execute("drop database if exists %s" % dbname)\n        # conn.close()\n        raise err\n\n\nif __name__ == "__main__":\n    test_subscribe_callback(connect())\n```\n\n### Insert with line protocol\n\n```python\nimport taos\nfrom taos import SmlProtocol, SmlPrecision\n\nconn = taos.connect()\ndbname = "pytest_line"\nconn.execute("drop database if exists %s" % dbname)\nconn.execute("create database if not exists %s precision \'us\'" % dbname)\nconn.select_db(dbname)\n\nlines = [\n    \'st,t1=3i64,t2=4f64,t3="t3" c1=3i64,c3=L"pass",c2=false,c4=4f64 1626006833639000000\',\n]\nconn.schemaless_insert(lines, taos.SmlProtocol.LINE_PROTOCOL, taos.SmlPrecision.NOT_CONFIGURED)\nprint("inserted")\n\nconn.schemaless_insert(lines, taos.SmlProtocol.LINE_PROTOCOL, taos.SmlPrecision.NOT_CONFIGURED)\n\nresult = conn.query("show tables")\nfor row in result:\n    print(row)\n\nconn.execute("drop database if exists %s" % dbname)\n```\n\n### Read with Pandas\n\n#### Method one\n\n```python\nimport pandas\nimport taos\n\nconn = taos.connect()\ndf: pandas.DataFrame = pandas.read_sql("select * from log.logs", conn)\n```\n\n#### Method Two\n\n```python\nimport pandas\nfrom sqlalchemy import create_engine\n\nengine = create_engine("taos://root:taosdata@localhost:6030/log")\ndf: pandas.DataFrame = pandas.read_sql("select * from logs", engine)\n```\n\n## Limitation\n\n- `taosrest` is designed to use with taosAdapter. If your TDengine version is older than v2.4.0.0, taosAdapter may not be available.\n\n## License\n\nWe use MIT license for Python connector.\n',
    'author': 'Taosdata Inc.',
    'author_email': 'support@taosdata.com',
    'maintainer': 'None',
    'maintainer_email': 'None',
    'url': 'None',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'extras_require': extras_require,
    'entry_points': entry_points,
    'python_requires': '>=3.7,<4.0',
}


setup(**setup_kwargs)
