Package: pykronos
# PyKronos## IntroductionThe contents of this file can be found in `demo.py` and are compiledinto `README.md`, so you can consume the readme while running thePython script to understand how it works.## Importing PyKronos And Some Useful UtilitiesCheck out `pykronos.client` and `pykronos.common.time` for some usefulutility functions.  PyKronos has a bunch of utilities to deal with`datetime` objects.```pythonfrom pykronos.client import ID_FIELDfrom pykronos.client import TIMESTAMP_FIELDfrom pykronos.client import KronosClientfrom pykronos.client import ResultOrderfrom pykronos.common.time import datetime_to_kronos_timefrom datetime import datetimefrom datetime import timedeltafrom dateutil.tz import tzutc```## Creating A ClientCreate a Kronos client with the URL of a running server.  Optionallyprovide a `namespace` to explicitly work with events in a particularnamespace.```pythonkc = KronosClient('http://localhost:8151', namespace='kronos')start = datetime.now(tz=tzutc())```### A Non-blocking ClientPass a `blocking=False` to the KronosClient constructor for a clientthat won't block on the Kronos server when you insert data.  Abackground thread will batch up data and send it to the server.  Thisis useful for logging/metrics collection on machines that can't waitfor a write acknowledgement.  An optional `sleep_block` argument,defaulting to `0.1` specifies how many seconds to wait between batchesto the server.  If the process running the client crashes beforeflushing events, those events will be lost.```pythonnonblocking = KronosClient('http://localhost:8151', namespace='kronos',blocking=False)```## Inserting EventsInsert events with the `put` command.  The argument is a dictionary ofstream names (e.g., `yourproduct.website.pageviews`) to a list ofJSON-encodable dictionaries to insert to each stream.```pythonkc.put({'yourproduct.website.pageviews': [{'source': 'http://test.com','browser': {'name': 'Firefox', 'version': 26},'pages': ['page1.html', 'page2.html']}],'yourproduct.website.clicks': [{'user': 40, 'num_clicks': 7},{'user': 42, 'num_clicks': 2}]})```### Optionally Add A TimestampBy default, each event will be timestamped on the client.  If you adda `TIMESTAMP_FIELD` argument, you can specify the time at which eachevent ocurred.```pythonoptional_time = datetime_to_kronos_time(start + timedelta(seconds=5))kc.put({'yourproduct.website.clicks': [{'user': 35, 'num_clicks': 10, TIMESTAMP_FIELD: optional_time}]})```## Retrieving EventsRetrieving events requires a stream name, a start datetime, and an enddatetime.  Note that an `ID_FIELD` and `@TIMESTAMP_FIELD` field areattached to each event.  The `ID_FIELD` is a UUID1-style identifierwith its time bits derived from the timestamp.  This allows event IDsto be roughly sortable by the time that they happened while providinga deterministic tiebreaker when two events happened at the same time.```pythonevents = kc.get('yourproduct.website.clicks',start,start + timedelta(minutes=10))for event in events:print 'Received event', eventlast_event_id = event[ID_FIELD]```### Event OrderBy default, events are returned in ascending order of their`ID_FIELD`.  Pass in an`order=ResultOrder.DESCENDING` argument tochange this behavior to be in descending order of `ID_FIELD`.```pythonevents = kc.get('yourproduct.website.clicks',start,start + timedelta(minutes=10),order=ResultOrder.DESCENDING)for event in events:print 'Reverse event', eventlast_event_id = event[ID_FIELD]```### Limiting EventsIf you only want to retrieve a limited number of events, use the`limit` argument.```pythonevents = kc.get('yourproduct.website.clicks',start,start + timedelta(minutes=10),order=ResultOrder.DESCENDING,limit=1)for event in events:print 'Limited event', eventlast_event_id = event[ID_FIELD]```## Getting A List Of StreamsTo see all streams available in this namespace, use `get_streams`.```pythonfor stream in kc.get_streams():print 'Found stream', stream```## Inferred SchemaYou can retrieve a schema for a stream. The schema is inferred from thestructure of the individual events. The schema protocol is based on JSON Schemav4.```pythonresponse = kc.infer_schema('yourproduct.website.clicks')print response['schema']```## Deleting EventsSometimes, we make an oopsie and need to delete some events.  The`delete` function takes similar arguments for the start and endtimestamps to delete.Note: The most common Kronos use cases are for write-mostly systemswith high-throughput reads.  As such, you can imagine that mostbackends will not be delete-optimized.  There's nothing in the KronosAPI that inherently makes deletes not performant, but we imagine somebackends will make tradeoffs to optimize their write and read paths atthe expense of fast deletes.```pythonkc.delete('yourproduct.website.clicks',start + timedelta(seconds=5),start + timedelta(minutes=10))events = kc.get('yourproduct.website.clicks',start,start + timedelta(minutes=10))for event in events:print 'Received event', event```