.. LiveView Python Client documentation master file, created by
   sphinx-quickstart on Tue Sep 21 20:25:56 2021.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.

LiveView Python Client Documentation
===========================================

.. toctree::
   :maxdepth: 3
   :caption: Contents:

The LiveView Python client lets you query, publish, and monitor data from a LiveView server with Python.

Getting Started
===============

Python version >= 3.6 is required.

To install the LiveView Python client:

.. code-block:: bash

   # Make sure $STREAMBASE_HOME is set
   $(eval sb-config --env --for-command-prompt)

   pip install $STREAMBASE_HOME/sdk/python/dist/lv_python_client-11.0.0-py3-none-any.whl

Run the following in a Python interpreter to verify that the Python client installed correctly:
::

   from tibco import liveview

   client = liveview.get_client('lv://localhost:11080')

   # If you have a LiveView server running on port 11080, this should succeed
   client.ensure_connection()

Snapshot and Live Queries
=========================

The client can run snapshot and live queries:
::

   from tibco import liveview
   import time
   from tibco.liveview.listeners import QueryListener
   from tibco.liveview import build_query as q

   # Get a client for a server running Hello LiveView
   client = liveview.get_client('lv://localhost:11080')

   # Perform a snapshot query
   query = q('ItemsInventory').select('*')
   snapshot = client.snapshot_query(query).to_dict()

   # Inspect the snapshot's schema and tuples
   print(snapshot['schema'])
   print(snapshot['data'])

   # Prepare a live query
   live_query = client.live_query(q('ItemsSales').select('*'))
   # Or
   # live_query = client.live_query_from_s('ItemsSales', 'SELECT * FROM ItemsSales')

   # Define a callback function which will be called with tuples whenever a tuple add event is received
   def tuple_added(lv_tuple):
       print(lv_tuple)

   with QueryListener(live_query, tuple_added=tuple_added):
       # Let the query listener run for 3 seconds
       time.sleep(3)

   # Now the query listener has stopped listening.

Live Result
===========

A LiveResult listens to a live query and maintains a result set of tuples as add, remove, and update events
come in.

**WARNING**: A LiveResult is intended for use only with queries that do not infinitely grow. A LiveResult does not
have a maximum capacity. Limit clauses may be used to guarantee one.
::

   import time
   from tibco import liveview
   from tibco.liveview.listeners import LiveResult

   client = liveview.get_client('lv://localhost:11080')
   live_query = client.live_query_from_s('ItemsSales', 'SELECT * FROM ItemsSales')

   live_result = LiveResult(live_query,
                            exception_raised=lambda e: print(e),
                            # Convert incoming tuples into Python types using the query's schema
                            convert_with_schema=True)

   # Get some results
   with live_result:
       time.sleep(3)

   '''The above is equivalent to
   live_result.start()
   time.sleep(3)
   live_result.stop()
   '''

   # Inspect the results.
   items, categories = live_result.get_columns('Item', 'category')
   for item, category in zip(items, categories):
       print(f'Item: {item}, Category: {category}')

Query Builder
=============

The LiveView Python Client comes with a query builder that allows you to intuitively construct queries:
::

   from tibco import liveview
   from tibco.liveview.listeners import LiveResult
   from tibco.liveview import build_query as q

   query = q('ItemsSales').select('Item', 'category').where(category='electronics')
   client = liveview.get_client('lv://localhost::11080')

   live_query = client.live_query(query)


API Reference
=============

LiveViewClient
--------------

.. autoclass:: tibco.liveview.LiveViewClient
   :members:
   :undoc-members:

Query
-----

.. autoclass:: tibco.liveview.Query
   :members:
   :undoc-members:

TableMetadata
-------------

.. autoclass:: tibco.liveview.models.TableMetadata
   :members:
   :undoc-members:

SnapshotResult
--------------

.. autoclass:: tibco.liveview.models.SnapshotResult
   :members:
   :undoc-members:

LiveQuery
---------

.. autoclass:: tibco.liveview.models.LiveQuery
   :members:
   :undoc-members:

BasicQueryListener
------------------

.. autoclass:: tibco.liveview.listeners.BasicQueryListener
   :members:
   :undoc-members:

QueryListener
-------------

.. autoclass:: tibco.liveview.listeners.QueryListener
   :members:
   :undoc-members:

LiveResult
----------

.. autoclass:: tibco.liveview.listeners.LiveResult
   :members:
   :undoc-members:

BufferedLVPublisher
-------------------

.. autoclass:: tibco.liveview.models.BufferedLVPublisher
   :members:
   :undoc-members:

Util
----

.. function:: convert_tuple_with_schema(liveview_tuple: dict, schema: dict) -> dict

   Try to convert a LiveView tuple's fields into their appropriate data types according to a schema. The schema
   is a dictionary that maps from string field names to string LiveView Type names from the below table.

   Fields are mapped to Python types according to the below table. If a conversion is unable to be performed, the
   field will be present in this function's return value without conversion.

   =============  ===========
   LiveView Type  Python Type
   =============  ===========
   blob           bytes
   bool           bool
   double         float
   int            int
   long           int
   string         str
   timestamp      datetime
   =============  ===========

.. function:: timestamp_to_datetime(ts) -> datetime.datetime

   Convert an absolute timestamp in milliseconds to a Python datetime.

.. function:: now_timestamp() -> int

   Return an absolute timestamp in milliseconds for the present moment.