python-thingsdb


Namepython-thingsdb JSON
Version 1.1.0 PyPI version JSON
download
home_pagehttps://github.com/thingsdb/python-thingsdb
SummaryThingsDB Connector
upload_time2024-04-10 11:13:34
maintainerNone
docs_urlNone
authorJeroen van der Heijden
requires_pythonNone
licenseMIT
keywords database connector
VCS
bugtrack_url
requirements msgpack deprecation
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![CI](https://github.com/thingsdb/python-thingsdb/workflows/CI/badge.svg)](https://github.com/thingsdb/python-thingsdb/actions)
[![Release Version](https://img.shields.io/github/release/thingsdb/python-thingsdb)](https://github.com/thingsdb/python-thingsdb/releases)

# Python connector for ThingsDB

> This library requires Python 3.6 or higher.

---------------------------------------

  * [Installation](#installation)
  * [Quick usage](#quick-usage)
  * [Client](#client)
    * [authenticate](#authenticate)
    * [close](#close)
    * [close_and_wait](#close_and_wait)
    * [connect](#connect)
    * [connect_pool](#connect_pool)
    * [get_default_scope](#get_default_scope)
    * [get_event_loop](#get_event_loop)
    * [get_rooms](#get_rooms)
    * [is_connected](#is_connected)
    * [is_websocket](#is_websocket)
    * [query](#query)
    * [reconnect](#reconnect)
    * [run](#run)
    * [set_default_scope](#set_default_scope)
    * [wait_closed](#wait_closed)
  * [Room](#room)
    * [methods](#room-methods)
    * [properties](#room-properties)
    * [join](#join)
    * [leave](#leave)
    * [emit](#emit)
    * [no_join](#no_join)
  * [Failed packages](#failed-packages)
  * [WebSockets](#websockets)
---------------------------------------

## Installation

Just use pip:

```
pip install python-thingsdb
```

Or, clone the project and use setup.py:

```
python setup.py install
```

## Quick usage

```python
import asyncio
from thingsdb.client import Client

async def hello_world():
    client = Client()

    # replace `localhost` with your ThingsDB server address
    await client.connect('localhost')

    try:
        # replace `admin` and `pass` with your username and password
        # or use a valid token string
        await client.authenticate('admin', 'pass')

        # perform the hello world code...
        print(await client.query('''
            "Hello World!";
        ''')

    finally:
        # the will close the client in a nice way
        await client.close_and_wait()

# run the hello world example
asyncio.get_event_loop().run_until_complete(hello_world())
```

## Client

This is an client using `asyncio` which can be used for running queries to
ThingsDB.


```python
thingsdb.client.Client(
    auto_reconnect: bool = True,
    ssl: Optional[Union[bool, ssl.SSLContext]] = None,
    loop: Optional[asyncio.AbstractEventLoop] = None
) -> Client
```
Initialize a ThingsDB client

#### Args

- *auto_reconnect (bool, optional)*:
    When set to `True`, the client will automatically
    reconnect when a connection is lost. If set to `False` and the
    connection gets lost, one may call the [reconnect()](#reconnect) method to
    make a new connection. The auto-reconnect option will listen to
    node changes and automatically start a reconnect loop if the
    *shutting-down* status is received from the node.
    Defaults to `True`.
- *ssl (SSLContext or bool, optional)*:
    Accepts an ssl.SSLContext for creating a secure connection
    using SSL/TLS. This argument may simply be set to `True` in
    which case a context using `ssl.PROTOCOL_TLS` is created.
    Defaults to `None`.
- *loop (AbstractEventLoop, optional)*:
    Can be used to run the client on a specific event loop.
    If this argument is not used, the default event loop will be
    used. Defaults to `None`.

### authenticate

```python
async Client().authenticate(
    *auth: Union[str, tuple],
    timeout: Optional[int] = 5
) -> None
```

Authenticate a ThingsDB connection.

#### Args

- *\*auth (str or (str, str))*:
    Argument `auth` can be be either a string with a token or a
    tuple with username and password. (the latter may be provided
    as two separate arguments
- *timeout (int, optional)*:
    Can be be used to control the maximum time in seconds for the
    client to wait for response on the authentication request.
    The timeout may be set to `None` in which case the client will
    wait forever on a response. Defaults to 5.

### close

```python
Client().close() -> None
```

Close the ThingsDB connection.

This method will return immediately so the connection may not be
closed yet after a call to `close()`. Use the [wait_closed()](#wait_closed) method
after calling this method if this is required.

### close_and_wait

```python
async Client().close_and_wait() -> None
```

Close and wait for the the connection to be closed.

This is equivalent of combining [close()](#close)) and [wait_closed()](#wait_closed).

### connect

```python
Client().connect(
    host: str,
    port: int = 9200,
    timeout: Optional[int] = 5
) -> asyncio.Future
```

Connect to ThingsDB.

This method will *only* create a connection, so the connection is not
authenticated yet. Use the [authenticate(..)](#authenticate) method after creating a
connection before using the connection.

#### Args

- *host (str)*:
    A hostname, IP address, FQDN or URI _(for WebSockets)_ to connect to.
- *port (int, optional)*:
    Integer value between 0 and 65535 and should be the port number
    where a ThingsDB node is listening to for client connections.
    Defaults to 9200. For WebSocket connections the port must be
    provided with the URI _(see host argument)_.
- *timeout (int, optional)*:
    Can be be used to control the maximum time the client will
    attempt to create a connection. The timeout may be set to
    `None` in which case the client will wait forever on a
    response. Defaults to 5.

### Returns

Future which should be awaited. The result of the future will be
set to `None` when successful.

> Do not use this method if the client is already
> connected. This can be checked with `client.is_connected()`.

### connect_pool

```python
Client().connect_pool(
    pool: list,
    *auth: Union[str, tuple]
) -> asyncio.Future
```

Connect using a connection pool.

When using a connection pool, the client will randomly choose a node
to connect to. When a node is going down, it will inform the client
so it will automatically re-connect to another node. Connections will
automatically authenticate so the connection pool requires credentials
to perform the authentication.

#### Examples

```python
await connect_pool([
    'node01.local',             # address or WebSocket URI as string
    'node02.local',             # port will default to 9200 or ignored for URI
    ('node03.local', 9201),     # ..or with an explicit port (ignored for URI)
], "admin", "pass")
```

#### Args

- *pool (list of addresses)*:
    Should be an iterable with node address strings, or tuples
    with `address` and `port` combinations in a tuple or list. For WebSockets,
    the address must be an URI with the port included. (e.g: `"ws://host:9270"`)
- *\*auth (str or (str, str))*:
    Argument `auth` can be be either a string with a token or a
    tuple with username and password. (the latter may be provided
    as two separate arguments

### Returns

Future which should be awaited. The result of the future will be
set to `None` when successful.

> Do not use this method if the client is already
> connected. This can be checked with `client.is_connected()`.


### get_default_scope

```python
Client().get_default_scope() -> str
```

Get the default scope.

The default scope may be changed with the [set_default_scope()](#set_default_scope) method.

#### Returns

The default scope which is used by the client when no specific scope is specified.


### get_event_loop

```python
Client().get_event_loop() -> asyncio.AbstractEventLoop
```

Can be used to get the event loop.

#### Returns

The event loop used by the client.

### get_rooms

```python
Client().get_rooms() -> tuple
```

Can be used to get the rooms which are joined by this client.

#### Returns

A `tuple` with unique `Room` instances.

### is_connected

```python
Client().is_connected() -> bool
```

Can be used to check if the client is connected.

#### Returns
`True` when the client is connected else `False`.


### is_websocket

```python
Client().is_websocket() -> bool
```

Can be used to check if the client is using a WebSocket connection.

#### Returns
`True` when the client is connected else `False`.

### query

```python
Client().query(
        code: str,
        scope: Optional[str] = None,
        timeout: Optional[int] = None,
        **kwargs: Any
) -> asyncio.Future
```

Query ThingsDB.

Use this method to run `code` in a scope.

#### Args

- *code (str)*:
    ThingsDB code to run.
- *scope (str, optional)*:
    Run the code in this scope. If not specified, the default scope
    will be used. See https://docs.thingsdb.net/v0/overview/scopes/
    for how to format a scope.
- *timeout (int, optional)*:
    Raise a time-out exception if no response is received within X
    seconds. If no time-out is given, the client will wait forever.
    Defaults to `None`.
- *\*\*kwargs (any, optional)*:
    Can be used to inject variable into the ThingsDB code.

#### Examples

Although we could just as easy have wrote everything in the
ThingsDB code itself, this example shows how to use **kwargs for
injecting variable into code. In this case the variable `book`.

```python
res = await client.query(".my_book = book;", book={
    'title': 'Manual ThingsDB'
})
```

#### Returns

Future which should be awaited. The result of the future will
contain the result of the ThingsDB code when successful.

> If the ThingsDB code will return with an exception, then this
> exception will be translated to a Python Exception which will be
> raised. See thingsdb.exceptions for all possible exceptions and
> https://docs.thingsdb.net/v0/errors/ for info on the error codes.

### reconnect

```python
async Client().reconnect() -> Optional[Future]
```

Re-connect to ThingsDB.

This method can be used, even when a connection still exists. In case
of a connection pool, a call to `reconnect()` will switch to another
node. If the client is already re-connecting, this method returns `None`,
otherwise, the reconnect `Future` is returned, await of the Future is
possible but not required.

### run

```python
Client().run(
    procedure: str,
    *args: Optional[Any],
    scope: Optional[str] = None,
    timeout: Optional[int] = None,
    **kwargs: Any
) -> asyncio.Future
```

Run a procedure.

Use this method to run a stored procedure in a scope.

#### Args

- *procedure (str)*:
    Name of the procedure to run.
- *\*args (any)*:
    Arguments which are injected as the procedure arguments.
    Instead of positional, the arguments may also be parsed using
    keyword arguments but not both at the same time.
- *scope (str, optional)*:
    Run the procedure in this scope. If not specified, the default
    scope will be used.
    See https://docs.thingsdb.net/v0/overview/scopes/ for how to
    format a scope.
- *timeout (int, optional)*:
    Raise a time-out exception if no response is received within X
    seconds. If no time-out is given, the client will wait forever.
    Defaults to `None`.
- *\*\*kwargs (any, optional)*:
     Arguments which are injected as the procedure arguments.
    Instead of by name, the arguments may also be parsed using
    positional arguments but not both at the same time.

#### Returns

Future which should be awaited. The result of the future will
contain the result of the ThingsDB procedure when successful.


> If the ThingsDB code will return with an exception, then this
> exception will be translated to a Python Exception which will be
> raised. See thingsdb.exceptions for all possible exceptions and
> https://docs.thingsdb.net/v0/errors/ for info on the error codes.


### set_default_scope

```python
Client().set_default_scope(scope: str) -> None
```

Set the default scope.

Can be used to change the default scope which is initially set to `@t`.

#### Args
- *scope (str)*:
    Set the default scope. A scope may start with either the `/`
    character, or `@`. Examples: `"//stuff"`, `"@:stuff"`, `"/node"`


### wait_closed

```python
async Client().wait_closed() -> None
```

Wait for a connection to close.

Can be used after calling the `close()` method to determine when the
connection is actually closed.


## Room

Rooms can be implemented to listen for events from ThingsDB rooms.

Se the example code:

```python
from thingsdb.room import Room, event

class Chat(Room):

    @event('msg')
    def on_msg(self, msg):
        print(msg)

```

This will listen for `msg` events on a ThingsDB room. To connect out class to a
room, you have to initialize the class with a `roomId` of some ThingsDB code which
returns the `roomId` as integer value. For example:

```python
# Create a chat instance. In this example we initialize our chat with some ThingsDB code
chat = Chat("""//ti
    // Create .chat room if the room does not exist.
    .has('chat') || .chat = room();

    // return the roomId.
    .chat.id();
""")

# Now we can join the room. (we assume that you have a ThingsDB client)
await chat.join(client)
```

#### Room Init Args
- *room (int/str)*:
    The room Id or ThingsDB code which returns the Id of the room.
    Examples are `123`, `'.my_room.id();'`
- *scope (str)*:
    Collection scope. If no scope is given, the scope will later
    be set to the default client scope once the room is joined.


## Room Methods

Besides implementing an `@event` handler, a room has also some methods which can be implemented to control or initialize a room.

### on_init(self) -> None
Called when a room is joined. This method will be called only once,
thus *not* after a re-connect like the `on_join(..)` method. This
method is guaranteed to be called *before* the `on_join(..)` method.

### on_join(self) -> None:
Called when a room is joined. Unlike the `on_init(..)` method,
the `on_join(..)` method will be called again after a re-connect.

This is an async method and usually the best method to perform
some ThingsDB queries (if required).

Unless the `wait` argument to the Room.join(..) function is explicitly
set to `0` or `None`, the first call to this method will finish before the
call to `Room.join()` is returned.

### on_leave(self) -> None:
Called after a leave room request. This event is *not* triggered
by ThingsDB when a client disconnects or when a node is shutting down.

### on_delete(self) -> None:
Called when the room is removed from ThingsDB.

### on_emit(self, event: str, *args) -> None:
Called when no event handler is configured for the event.
By default, the `on_emit` will display a "debug" log message when called to
show that no handler for the event is found.

## Room Properties

The following properties are available on a room instance. Note that some properties
might return `None` as long as a room is not joined.

Property | Description
-------- | -----------
`id`     | Returns the roomId.
`scope`  | Returns the scope of the room.
`client` | Returns the associated client of the room.

### join

```python
Room().join(client: Client, wait: Optional[float] = 60.0) -> None
```

Joins the room.

#### Args
- client *(thingsdb.client.Client)*:
        ThingsDB client instance.
- wait *(float)*:
    Max time (in seconds) to wait for the first `on_join` call.
    If wait is set to `0` or `None`, the join method will not wait for
    the first `on_join` call to happen.


### leave

```python
Room().leave() -> None
```

Leave the room. If the room is not found, a `LookupError` will be raised.

### emit

```python
Room().emit(event: str, *args: Optional[Any],) -> asyncio.Future
```

Emit an event to a room.

#### Args

- *event (str)*:
    Name of the event to emit.
- *\*args (any)*:
    Additional argument to send with the event.

#### Returns

Future which should be awaited. The result of the future will
be set to `None` when successful.

### no_join

```python
Room().no_join(client: Client) -> None
```

Only translate the code _(or test the Id)_ to a room Id. This is useful if you only
want to use the room to emit events and not listen to events.

#### Args
- client *(thingsdb.client.Client)*:
        ThingsDB client instance.


## Failed packages

```python
set_package_fail_file(fn: str = '') -> None
```

Configure a file name to dump the last failed package.

Only the MessagePack data will be stored in this file, not the package
header. This is useful for debugging packages which fail to unpack.
Note that only a single fail file can be used which is active (or not) for
all clients.

When empty (`''`), a failed package will *not* be dumped to file.

```python
from thingsdb.client import set_package_fail_file

set_package_fail_file('/tmp/thingsdb-invalid-data.mp')

# When a package is received which fails to unpack, the data from this package
# will be stored to file.
```


## WebSockets

Since ThingsDB 1.6 has received WebSocket support. The Python client is able to use the WebSockets protocol by providing the `host` as URI.
For WebSocket connections,the `port` argument will be ignored and must be specified with the URI instead.

Default the `websockets` package is **not included** when installing this connector.

If you want to use WebSockets, make sure to install the package:

```
pip install websockets
```

For example:

```python
import asyncio
from thingsdb.client import Client

async def hello_world():
    client = Client()

    # replace `ws://localhost:9270` with your URI
    await client.connect('ws://localhost:9270')

    # for a secure connection, use wss:// and provide an SSL context, example:
    # (ssl can be set either to True or False, or an SSLContext)
    #
    #   await client.connect('wss://localhost:9270', ssl=True)

    try:
        # replace `admin` and `pass` with your username and password
        # or use a valid token string
        await client.authenticate('admin', 'pass')

        # perform the hello world code...
        print(await client.query('''
            "Hello World!";
        ''')

    finally:
        # the will close the client in a nice way
        await client.close_and_wait()

# run the hello world example
asyncio.get_event_loop().run_until_complete(hello_world())
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/thingsdb/python-thingsdb",
    "name": "python-thingsdb",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": "database connector",
    "author": "Jeroen van der Heijden",
    "author_email": "jeroen@cesbit.com",
    "download_url": "https://files.pythonhosted.org/packages/47/bb/0de2b0d715e1150aefb1ec2e1505c1ff5642e0ba18cf43d35b5309063e80/python-thingsdb-1.1.0.tar.gz",
    "platform": null,
    "description": "[![CI](https://github.com/thingsdb/python-thingsdb/workflows/CI/badge.svg)](https://github.com/thingsdb/python-thingsdb/actions)\n[![Release Version](https://img.shields.io/github/release/thingsdb/python-thingsdb)](https://github.com/thingsdb/python-thingsdb/releases)\n\n# Python connector for ThingsDB\n\n> This library requires Python 3.6 or higher.\n\n---------------------------------------\n\n  * [Installation](#installation)\n  * [Quick usage](#quick-usage)\n  * [Client](#client)\n    * [authenticate](#authenticate)\n    * [close](#close)\n    * [close_and_wait](#close_and_wait)\n    * [connect](#connect)\n    * [connect_pool](#connect_pool)\n    * [get_default_scope](#get_default_scope)\n    * [get_event_loop](#get_event_loop)\n    * [get_rooms](#get_rooms)\n    * [is_connected](#is_connected)\n    * [is_websocket](#is_websocket)\n    * [query](#query)\n    * [reconnect](#reconnect)\n    * [run](#run)\n    * [set_default_scope](#set_default_scope)\n    * [wait_closed](#wait_closed)\n  * [Room](#room)\n    * [methods](#room-methods)\n    * [properties](#room-properties)\n    * [join](#join)\n    * [leave](#leave)\n    * [emit](#emit)\n    * [no_join](#no_join)\n  * [Failed packages](#failed-packages)\n  * [WebSockets](#websockets)\n---------------------------------------\n\n## Installation\n\nJust use pip:\n\n```\npip install python-thingsdb\n```\n\nOr, clone the project and use setup.py:\n\n```\npython setup.py install\n```\n\n## Quick usage\n\n```python\nimport asyncio\nfrom thingsdb.client import Client\n\nasync def hello_world():\n    client = Client()\n\n    # replace `localhost` with your ThingsDB server address\n    await client.connect('localhost')\n\n    try:\n        # replace `admin` and `pass` with your username and password\n        # or use a valid token string\n        await client.authenticate('admin', 'pass')\n\n        # perform the hello world code...\n        print(await client.query('''\n            \"Hello World!\";\n        ''')\n\n    finally:\n        # the will close the client in a nice way\n        await client.close_and_wait()\n\n# run the hello world example\nasyncio.get_event_loop().run_until_complete(hello_world())\n```\n\n## Client\n\nThis is an client using `asyncio` which can be used for running queries to\nThingsDB.\n\n\n```python\nthingsdb.client.Client(\n    auto_reconnect: bool = True,\n    ssl: Optional[Union[bool, ssl.SSLContext]] = None,\n    loop: Optional[asyncio.AbstractEventLoop] = None\n) -> Client\n```\nInitialize a ThingsDB client\n\n#### Args\n\n- *auto_reconnect (bool, optional)*:\n    When set to `True`, the client will automatically\n    reconnect when a connection is lost. If set to `False` and the\n    connection gets lost, one may call the [reconnect()](#reconnect) method to\n    make a new connection. The auto-reconnect option will listen to\n    node changes and automatically start a reconnect loop if the\n    *shutting-down* status is received from the node.\n    Defaults to `True`.\n- *ssl (SSLContext or bool, optional)*:\n    Accepts an ssl.SSLContext for creating a secure connection\n    using SSL/TLS. This argument may simply be set to `True` in\n    which case a context using `ssl.PROTOCOL_TLS` is created.\n    Defaults to `None`.\n- *loop (AbstractEventLoop, optional)*:\n    Can be used to run the client on a specific event loop.\n    If this argument is not used, the default event loop will be\n    used. Defaults to `None`.\n\n### authenticate\n\n```python\nasync Client().authenticate(\n    *auth: Union[str, tuple],\n    timeout: Optional[int] = 5\n) -> None\n```\n\nAuthenticate a ThingsDB connection.\n\n#### Args\n\n- *\\*auth (str or (str, str))*:\n    Argument `auth` can be be either a string with a token or a\n    tuple with username and password. (the latter may be provided\n    as two separate arguments\n- *timeout (int, optional)*:\n    Can be be used to control the maximum time in seconds for the\n    client to wait for response on the authentication request.\n    The timeout may be set to `None` in which case the client will\n    wait forever on a response. Defaults to 5.\n\n### close\n\n```python\nClient().close() -> None\n```\n\nClose the ThingsDB connection.\n\nThis method will return immediately so the connection may not be\nclosed yet after a call to `close()`. Use the [wait_closed()](#wait_closed) method\nafter calling this method if this is required.\n\n### close_and_wait\n\n```python\nasync Client().close_and_wait() -> None\n```\n\nClose and wait for the the connection to be closed.\n\nThis is equivalent of combining [close()](#close)) and [wait_closed()](#wait_closed).\n\n### connect\n\n```python\nClient().connect(\n    host: str,\n    port: int = 9200,\n    timeout: Optional[int] = 5\n) -> asyncio.Future\n```\n\nConnect to ThingsDB.\n\nThis method will *only* create a connection, so the connection is not\nauthenticated yet. Use the [authenticate(..)](#authenticate) method after creating a\nconnection before using the connection.\n\n#### Args\n\n- *host (str)*:\n    A hostname, IP address, FQDN or URI _(for WebSockets)_ to connect to.\n- *port (int, optional)*:\n    Integer value between 0 and 65535 and should be the port number\n    where a ThingsDB node is listening to for client connections.\n    Defaults to 9200. For WebSocket connections the port must be\n    provided with the URI _(see host argument)_.\n- *timeout (int, optional)*:\n    Can be be used to control the maximum time the client will\n    attempt to create a connection. The timeout may be set to\n    `None` in which case the client will wait forever on a\n    response. Defaults to 5.\n\n### Returns\n\nFuture which should be awaited. The result of the future will be\nset to `None` when successful.\n\n> Do not use this method if the client is already\n> connected. This can be checked with `client.is_connected()`.\n\n### connect_pool\n\n```python\nClient().connect_pool(\n    pool: list,\n    *auth: Union[str, tuple]\n) -> asyncio.Future\n```\n\nConnect using a connection pool.\n\nWhen using a connection pool, the client will randomly choose a node\nto connect to. When a node is going down, it will inform the client\nso it will automatically re-connect to another node. Connections will\nautomatically authenticate so the connection pool requires credentials\nto perform the authentication.\n\n#### Examples\n\n```python\nawait connect_pool([\n    'node01.local',             # address or WebSocket URI as string\n    'node02.local',             # port will default to 9200 or ignored for URI\n    ('node03.local', 9201),     # ..or with an explicit port (ignored for URI)\n], \"admin\", \"pass\")\n```\n\n#### Args\n\n- *pool (list of addresses)*:\n    Should be an iterable with node address strings, or tuples\n    with `address` and `port` combinations in a tuple or list. For WebSockets,\n    the address must be an URI with the port included. (e.g: `\"ws://host:9270\"`)\n- *\\*auth (str or (str, str))*:\n    Argument `auth` can be be either a string with a token or a\n    tuple with username and password. (the latter may be provided\n    as two separate arguments\n\n### Returns\n\nFuture which should be awaited. The result of the future will be\nset to `None` when successful.\n\n> Do not use this method if the client is already\n> connected. This can be checked with `client.is_connected()`.\n\n\n### get_default_scope\n\n```python\nClient().get_default_scope() -> str\n```\n\nGet the default scope.\n\nThe default scope may be changed with the [set_default_scope()](#set_default_scope) method.\n\n#### Returns\n\nThe default scope which is used by the client when no specific scope is specified.\n\n\n### get_event_loop\n\n```python\nClient().get_event_loop() -> asyncio.AbstractEventLoop\n```\n\nCan be used to get the event loop.\n\n#### Returns\n\nThe event loop used by the client.\n\n### get_rooms\n\n```python\nClient().get_rooms() -> tuple\n```\n\nCan be used to get the rooms which are joined by this client.\n\n#### Returns\n\nA `tuple` with unique `Room` instances.\n\n### is_connected\n\n```python\nClient().is_connected() -> bool\n```\n\nCan be used to check if the client is connected.\n\n#### Returns\n`True` when the client is connected else `False`.\n\n\n### is_websocket\n\n```python\nClient().is_websocket() -> bool\n```\n\nCan be used to check if the client is using a WebSocket connection.\n\n#### Returns\n`True` when the client is connected else `False`.\n\n### query\n\n```python\nClient().query(\n        code: str,\n        scope: Optional[str] = None,\n        timeout: Optional[int] = None,\n        **kwargs: Any\n) -> asyncio.Future\n```\n\nQuery ThingsDB.\n\nUse this method to run `code` in a scope.\n\n#### Args\n\n- *code (str)*:\n    ThingsDB code to run.\n- *scope (str, optional)*:\n    Run the code in this scope. If not specified, the default scope\n    will be used. See https://docs.thingsdb.net/v0/overview/scopes/\n    for how to format a scope.\n- *timeout (int, optional)*:\n    Raise a time-out exception if no response is received within X\n    seconds. If no time-out is given, the client will wait forever.\n    Defaults to `None`.\n- *\\*\\*kwargs (any, optional)*:\n    Can be used to inject variable into the ThingsDB code.\n\n#### Examples\n\nAlthough we could just as easy have wrote everything in the\nThingsDB code itself, this example shows how to use **kwargs for\ninjecting variable into code. In this case the variable `book`.\n\n```python\nres = await client.query(\".my_book = book;\", book={\n    'title': 'Manual ThingsDB'\n})\n```\n\n#### Returns\n\nFuture which should be awaited. The result of the future will\ncontain the result of the ThingsDB code when successful.\n\n> If the ThingsDB code will return with an exception, then this\n> exception will be translated to a Python Exception which will be\n> raised. See thingsdb.exceptions for all possible exceptions and\n> https://docs.thingsdb.net/v0/errors/ for info on the error codes.\n\n### reconnect\n\n```python\nasync Client().reconnect() -> Optional[Future]\n```\n\nRe-connect to ThingsDB.\n\nThis method can be used, even when a connection still exists. In case\nof a connection pool, a call to `reconnect()` will switch to another\nnode. If the client is already re-connecting, this method returns `None`,\notherwise, the reconnect `Future` is returned, await of the Future is\npossible but not required.\n\n### run\n\n```python\nClient().run(\n    procedure: str,\n    *args: Optional[Any],\n    scope: Optional[str] = None,\n    timeout: Optional[int] = None,\n    **kwargs: Any\n) -> asyncio.Future\n```\n\nRun a procedure.\n\nUse this method to run a stored procedure in a scope.\n\n#### Args\n\n- *procedure (str)*:\n    Name of the procedure to run.\n- *\\*args (any)*:\n    Arguments which are injected as the procedure arguments.\n    Instead of positional, the arguments may also be parsed using\n    keyword arguments but not both at the same time.\n- *scope (str, optional)*:\n    Run the procedure in this scope. If not specified, the default\n    scope will be used.\n    See https://docs.thingsdb.net/v0/overview/scopes/ for how to\n    format a scope.\n- *timeout (int, optional)*:\n    Raise a time-out exception if no response is received within X\n    seconds. If no time-out is given, the client will wait forever.\n    Defaults to `None`.\n- *\\*\\*kwargs (any, optional)*:\n     Arguments which are injected as the procedure arguments.\n    Instead of by name, the arguments may also be parsed using\n    positional arguments but not both at the same time.\n\n#### Returns\n\nFuture which should be awaited. The result of the future will\ncontain the result of the ThingsDB procedure when successful.\n\n\n> If the ThingsDB code will return with an exception, then this\n> exception will be translated to a Python Exception which will be\n> raised. See thingsdb.exceptions for all possible exceptions and\n> https://docs.thingsdb.net/v0/errors/ for info on the error codes.\n\n\n### set_default_scope\n\n```python\nClient().set_default_scope(scope: str) -> None\n```\n\nSet the default scope.\n\nCan be used to change the default scope which is initially set to `@t`.\n\n#### Args\n- *scope (str)*:\n    Set the default scope. A scope may start with either the `/`\n    character, or `@`. Examples: `\"//stuff\"`, `\"@:stuff\"`, `\"/node\"`\n\n\n### wait_closed\n\n```python\nasync Client().wait_closed() -> None\n```\n\nWait for a connection to close.\n\nCan be used after calling the `close()` method to determine when the\nconnection is actually closed.\n\n\n## Room\n\nRooms can be implemented to listen for events from ThingsDB rooms.\n\nSe the example code:\n\n```python\nfrom thingsdb.room import Room, event\n\nclass Chat(Room):\n\n    @event('msg')\n    def on_msg(self, msg):\n        print(msg)\n\n```\n\nThis will listen for `msg` events on a ThingsDB room. To connect out class to a\nroom, you have to initialize the class with a `roomId` of some ThingsDB code which\nreturns the `roomId` as integer value. For example:\n\n```python\n# Create a chat instance. In this example we initialize our chat with some ThingsDB code\nchat = Chat(\"\"\"//ti\n    // Create .chat room if the room does not exist.\n    .has('chat') || .chat = room();\n\n    // return the roomId.\n    .chat.id();\n\"\"\")\n\n# Now we can join the room. (we assume that you have a ThingsDB client)\nawait chat.join(client)\n```\n\n#### Room Init Args\n- *room (int/str)*:\n    The room Id or ThingsDB code which returns the Id of the room.\n    Examples are `123`, `'.my_room.id();'`\n- *scope (str)*:\n    Collection scope. If no scope is given, the scope will later\n    be set to the default client scope once the room is joined.\n\n\n## Room Methods\n\nBesides implementing an `@event` handler, a room has also some methods which can be implemented to control or initialize a room.\n\n### on_init(self) -> None\nCalled when a room is joined. This method will be called only once,\nthus *not* after a re-connect like the `on_join(..)` method. This\nmethod is guaranteed to be called *before* the `on_join(..)` method.\n\n### on_join(self) -> None:\nCalled when a room is joined. Unlike the `on_init(..)` method,\nthe `on_join(..)` method will be called again after a re-connect.\n\nThis is an async method and usually the best method to perform\nsome ThingsDB queries (if required).\n\nUnless the `wait` argument to the Room.join(..) function is explicitly\nset to `0` or `None`, the first call to this method will finish before the\ncall to `Room.join()` is returned.\n\n### on_leave(self) -> None:\nCalled after a leave room request. This event is *not* triggered\nby ThingsDB when a client disconnects or when a node is shutting down.\n\n### on_delete(self) -> None:\nCalled when the room is removed from ThingsDB.\n\n### on_emit(self, event: str, *args) -> None:\nCalled when no event handler is configured for the event.\nBy default, the `on_emit` will display a \"debug\" log message when called to\nshow that no handler for the event is found.\n\n## Room Properties\n\nThe following properties are available on a room instance. Note that some properties\nmight return `None` as long as a room is not joined.\n\nProperty | Description\n-------- | -----------\n`id`     | Returns the roomId.\n`scope`  | Returns the scope of the room.\n`client` | Returns the associated client of the room.\n\n### join\n\n```python\nRoom().join(client: Client, wait: Optional[float] = 60.0) -> None\n```\n\nJoins the room.\n\n#### Args\n- client *(thingsdb.client.Client)*:\n        ThingsDB client instance.\n- wait *(float)*:\n    Max time (in seconds) to wait for the first `on_join` call.\n    If wait is set to `0` or `None`, the join method will not wait for\n    the first `on_join` call to happen.\n\n\n### leave\n\n```python\nRoom().leave() -> None\n```\n\nLeave the room. If the room is not found, a `LookupError` will be raised.\n\n### emit\n\n```python\nRoom().emit(event: str, *args: Optional[Any],) -> asyncio.Future\n```\n\nEmit an event to a room.\n\n#### Args\n\n- *event (str)*:\n    Name of the event to emit.\n- *\\*args (any)*:\n    Additional argument to send with the event.\n\n#### Returns\n\nFuture which should be awaited. The result of the future will\nbe set to `None` when successful.\n\n### no_join\n\n```python\nRoom().no_join(client: Client) -> None\n```\n\nOnly translate the code _(or test the Id)_ to a room Id. This is useful if you only\nwant to use the room to emit events and not listen to events.\n\n#### Args\n- client *(thingsdb.client.Client)*:\n        ThingsDB client instance.\n\n\n## Failed packages\n\n```python\nset_package_fail_file(fn: str = '') -> None\n```\n\nConfigure a file name to dump the last failed package.\n\nOnly the MessagePack data will be stored in this file, not the package\nheader. This is useful for debugging packages which fail to unpack.\nNote that only a single fail file can be used which is active (or not) for\nall clients.\n\nWhen empty (`''`), a failed package will *not* be dumped to file.\n\n```python\nfrom thingsdb.client import set_package_fail_file\n\nset_package_fail_file('/tmp/thingsdb-invalid-data.mp')\n\n# When a package is received which fails to unpack, the data from this package\n# will be stored to file.\n```\n\n\n## WebSockets\n\nSince ThingsDB 1.6 has received WebSocket support. The Python client is able to use the WebSockets protocol by providing the `host` as URI.\nFor WebSocket connections,the `port` argument will be ignored and must be specified with the URI instead.\n\nDefault the `websockets` package is **not included** when installing this connector.\n\nIf you want to use WebSockets, make sure to install the package:\n\n```\npip install websockets\n```\n\nFor example:\n\n```python\nimport asyncio\nfrom thingsdb.client import Client\n\nasync def hello_world():\n    client = Client()\n\n    # replace `ws://localhost:9270` with your URI\n    await client.connect('ws://localhost:9270')\n\n    # for a secure connection, use wss:// and provide an SSL context, example:\n    # (ssl can be set either to True or False, or an SSLContext)\n    #\n    #   await client.connect('wss://localhost:9270', ssl=True)\n\n    try:\n        # replace `admin` and `pass` with your username and password\n        # or use a valid token string\n        await client.authenticate('admin', 'pass')\n\n        # perform the hello world code...\n        print(await client.query('''\n            \"Hello World!\";\n        ''')\n\n    finally:\n        # the will close the client in a nice way\n        await client.close_and_wait()\n\n# run the hello world example\nasyncio.get_event_loop().run_until_complete(hello_world())\n```\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "ThingsDB Connector",
    "version": "1.1.0",
    "project_urls": {
        "Homepage": "https://github.com/thingsdb/python-thingsdb"
    },
    "split_keywords": [
        "database",
        "connector"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "47bb0de2b0d715e1150aefb1ec2e1505c1ff5642e0ba18cf43d35b5309063e80",
                "md5": "c4433c472ded9423bca9e7766e94c184",
                "sha256": "f9b396b1d44304bd7a5fab233f6031c6b92dc5fe3e2dd2ddf4ac661b4129542a"
            },
            "downloads": -1,
            "filename": "python-thingsdb-1.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "c4433c472ded9423bca9e7766e94c184",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 27880,
            "upload_time": "2024-04-10T11:13:34",
            "upload_time_iso_8601": "2024-04-10T11:13:34.542758Z",
            "url": "https://files.pythonhosted.org/packages/47/bb/0de2b0d715e1150aefb1ec2e1505c1ff5642e0ba18cf43d35b5309063e80/python-thingsdb-1.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-10 11:13:34",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "thingsdb",
    "github_project": "python-thingsdb",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "msgpack",
            "specs": [
                [
                    ">=",
                    "0.6.2"
                ]
            ]
        },
        {
            "name": "deprecation",
            "specs": []
        }
    ],
    "lcname": "python-thingsdb"
}
        
Elapsed time: 0.24206s