In [1]:
import os, sys, inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)

In [2]:
sys.path.append('/Users/Elena/Desktop/TimeSeries/')

In [3]:
import time
import signal
import subprocess
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
sns.set_style('white')
sns.set_context('notebook')


//anaconda/envs/py35/lib/python3.5/site-packages/IPython/html.py:14: ShimWarning: The `IPython.html` package has been deprecated. You should import from `notebook` instead. `IPython.html.widgets` has moved to `ipywidgets`.
  "`IPython.html.widgets` has moved to `ipywidgets`.", ShimWarning)

In [4]:
from web.web_for_coverage import WebInterface
from timeseries.TimeSeries import TimeSeries

TIMESERIES WEB API

insert_ts(self, pk, ts):

    """
    Insert a timeseries into the database by sending a request to the server.

    Parameters
    ----------
    primary_key: int
        a unique identifier for the timeseries

    ts: a TimeSeries object
        the timeseries object intended to be inserted to database
    """

delete_ts(self, pk):

"""
Delete a timeseries from the database by sending a request to the server.

Parameters
----------
primary_key: int
    a unique identifier for the timeseries
"""



upsert_meta(self, pk, md):

"""
Upserting metadata into the timeseries in the database designated by the promary key by sending the server a request.

Parameters
----------
primary_key: int
    a unique identifier for the timeseries

metadata_dict: dict
    the metadata to upserted into the timeseries
"""


select(self, md={}, fields=None, additional=None):

"""
Selecting timeseries elements in the database that match the criteria
set in metadata_dict and return corresponding fields with additional
features.

Parameters
----------
metadata_dict: dict
    the selection criteria (filters)
    (Options : 'blarg', 'order')

fields: dict
    If not `None`, only these fields of the timeseries are returned.
    Otherwise, the timeseries are returned.

additional: dict
    additional computation to perform on the query matches before they're
    returned. Currently provide "sort_by" and "limit" functionality

"""


augmented_select(self, proc, target, arg=None, md={}, additional=None):

"""
Parameters
----------
proc : enum
    which of the modules in procs,
    or name of module in procs with coroutine main.
    (Options: 'corr', 'junk', 'stats')
target : array of fieldnames
    will be mapped to the array of results from the coroutine.
    If the target is None rather than a list of fields, we'll assume no upserting
arg : additional argument
    (ex : Timeseries object)
metadata_dict : dict
                store info for TimeSeries other than TimeSeries object itself
                (ex. vantage point is metadata_dict['ts-14']['vp']
additional : dict
            (Options: {"sort_by":"-order"})

Returns
-------
tsdb status & payload
"""


add_trigger(self, proc, onwhat, target, arg=None):

"""
Send the server a request to add a trigger.

Parameters
----------
`proc` : enum
    which of the modules in procs,
    or name of module in procs with coroutine main.
    (Options: 'corr', 'junk', 'stats')
`onwhat` :
    which op is this trigger running on
    (ex : "insert_ts")
`target` : array of fieldnames
    will be mapped to the array of results from the coroutine.
    If the target is None rather than a list of fields, we'll assume no upserting
`arg` :
    additional argument
    (ex : Timeseries object)
"""

remove_trigger(self, proc, onwhat, target=None):

"""
Send the server a request to REMOVE a trigger.

Parameters
----------
`proc` : enum
    which of the modules in procs,
    or name of module in procs with coroutine main.
    (Options: 'corr', 'junk', 'stats')
`onwhat` :
    which op is this trigger running on
    (ex : "insert_ts")
`target` : array of fieldnames
    will be mapped to the array of results from the coroutine.
    If the target is None rather than a list of fields, we'll assume no upserting
"""

Here in the notebook we use subprocess to launch our server, to see the output better, we strongly suggest to launch server directly in terminal whenever possible!

Below queries are just to offer you an sense of how our web api works, feel free to try more with the api description we proveded above!


In [5]:
# server = subprocess.Popen(['python', '../go_persistent_server.py'])
# time.sleep(3)

# web = subprocess.Popen(['python', '../go_web.py'])
# time.sleep(3)

In [5]:
web_interface = WebInterface()

In [26]:
results = web_interface.add_trigger(
            'junk', 'insert_ts', None, 'db:one:ts')
assert results[0] == 200
print(results)


(200, b'"Successfully added trigger"')

In [27]:
results = web_interface.add_trigger(
            'stats', 'insert_ts', ['mean', 'std'], None)
assert results[0] == 200
print(results[1])


b'"Successfully added trigger"'

In [8]:
def tsmaker(m, s, j):
    '''
    Helper function: randomly generates a time series for testing.

    Parameters
    ----------
    m : float
        Mean value for generating time series data
    s : float
        Standard deviation value for generating time series data
    j : float
        Quantifies the "jitter" to add to the time series data

    Returns
    -------
    A time series and associated meta data.
    '''

    # generate metadata
    meta = {}
    meta['order'] = int(np.random.choice(
        [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]))
    meta['blarg'] = int(np.random.choice([1, 2]))

    # generate time series data
    t = np.arange(0.0, 1.0, 0.01)
    v = norm.pdf(t, m, s) + j * np.random.randn(ts_length)

    # return time series and metadata
    return meta, TimeSeries(t, v)

In [20]:
mus = np.random.uniform(low=0.0, high=1.0, size=50)
sigs = np.random.uniform(low=0.05, high=0.4, size=50)
jits = np.random.uniform(low=0.05, high=0.2, size=50)
ts_length = 100

# initialize dictionaries for time series and their metadata
tsdict = {}
metadict = {}
for i, m, s, j in zip(range(50), mus, sigs, jits):
    meta, tsrs = tsmaker(m, s, j)
    # the primary key format is ts-1, ts-2, etc
    pk = "ts-{}".format(i)
    tsdict[pk] = tsrs
    meta['vp'] = False # augment metadata with a boolean asking if this is a  VP.
    metadict[pk] = meta


vpkeys = ["ts-{}".format(i) for i in np.random.choice(range(50), size=5, replace=False)]
for i in range(5):
    # add 5 triggers to upsert distances to these vantage points
    # data = json.dumps({'proc':'corr', 'onwhat':'insert_ts', 'target':["d_vp-{}".format(i)], 'arg':tsdict[vpkeys[i]].to_json()})
    # r = requests.post(self.web_url+'/add_trigger', data)

    r = web_interface.add_trigger('corr', 'insert_ts', ["d_vp-{}".format(i)], tsdict[vpkeys[i]].to_json())
    assert(r[0] == 200)
    # change the metadata for the vantage points to have meta['vp']=True
    metadict[vpkeys[i]]['vp'] = True

Having set up the triggers, now insert the time series, and upsert the metadata

==========================================

When it's first time to insert these keys in TSDB_server, insert_ts will work and return TSDBStatus.OK

==========================================


In [21]:
for k in tsdict:
    results = web_interface.insert_ts(k, tsdict[k])
    assert results[0] == 200
    # upsert meta
    results = web_interface.upsert_meta(k, metadict[k])
    assert results[0] == 200

In [22]:
results = web_interface.add_trigger(
            'junk', 'insert_ts', None, 'db:one:ts')

In [23]:
results


Out[23]:
(200, b'"Successfully added trigger"')

In [24]:
# ==========================================
# However if it's not first time to insert these keys,
# insert_ts will return TSDBStatus.INVALID_KEY
# ==========================================
# pick a random pk
idx = np.random.choice(list(tsdict.keys()))

# check that the time series is there now
results = web_interface.select({"primary_key": idx})
assert results[0] == 200

In [25]:
# delete an existing time series
results = web_interface.delete_ts(idx)
assert results[0] == 200

In [18]:
# check that the time series is no longer there
results = web_interface.select({"md":{"order": 1}, "fields":["ts"], "additional":{"sort_by":"-order"}})
assert results[0] == 200

In [19]:
# add the time series back in
results = web_interface.insert_ts(idx, tsdict[idx])
assert results[0] == 200