11import os
2- import time
32import logging
4- import collections
5-
63import requests
4+ from .buffer import Buffer
75
8- from collections import deque
96from io import StringIO
107from transit .writer import Writer
118from transit .reader import Reader
1613DEFAULT_BATCH_DELAY_MILLIS = 60000
1714DEFAULT_STITCH_URL = 'https://api.stitchdata.com/v2/import/push'
1815
19- BufferEntry = collections .namedtuple ('BufferEntry' , 'timestamp value callback_arg' )
2016
2117class Client (object ):
2218
23- class Buffer (object ):
24-
25- MAX_BATCH_SIZE_BYTES = 4194304
26- MAX_MESSAGES_PER_BATCH = 10000
27-
28- _queue = deque ()
29- _available_bytes = 0
30-
31- def put (self , value , callback_arg ):
32- self ._queue .append (BufferEntry (timestamp = time .time ()* 1000 , value = value , callback_arg = callback_arg ))
33- self ._available_bytes += len (value .encode ("utf8" ))
34-
35- def take (self , batch_size_bytes , batch_delay_millis ):
36- if len (self ._queue ) == 0 :
37- return None
38-
39- ready = self ._available_bytes >= batch_size_bytes or \
40- len (self ._queue ) >= self .MAX_MESSAGES_PER_BATCH or \
41- time .time ()* 1000 - self ._queue [0 ].timestamp >= batch_delay_millis
42-
43- if not ready :
44- return None
45-
46- entries = []
47- size = 2
48-
49- while len (self ._queue ) > 0 and \
50- size + len (self ._queue [0 ].value .encode ("utf8" )) < self .MAX_BATCH_SIZE_BYTES :
51- entry = self ._queue .popleft ()
52-
53- # add one for the comma that will be needed to link entries together
54- entry_size = len (entry .value .encode ("utf8" ))
55- size += entry_size + 1
56- self ._available_bytes -= entry_size
57- entries .append (entry )
58-
59- return entries
60-
6119 _buffer = Buffer ()
6220
6321 def __init__ (self ,
@@ -70,7 +28,8 @@ def __init__(self,
7028 batch_size_bytes = DEFAULT_BATCH_SIZE_BYTES ,
7129 batch_delay_millis = DEFAULT_BATCH_DELAY_MILLIS ):
7230
73- assert isinstance (client_id , int ), 'client_id is not an integer: {}' .format (client_id )
31+ assert (isinstance (client_id , int ),
32+ 'client_id is not an integer: {}' .format (client_id ))
7433
7534 self .client_id = client_id
7635 self .token = token
@@ -81,7 +40,7 @@ def __init__(self,
8140 self .batch_delay_millis = batch_delay_millis
8241 self .callback_function = callback_function
8342
84- def push (self , message , callback_arg = None ):
43+ def push (self , message , callback_arg = None ):
8544 """
8645 message must be a dict with at least these keys:
8746 action, table_name, key_names, sequence, data
@@ -91,10 +50,8 @@ def push(self, message, callback_arg = None):
9150
9251 if message ['action' ] == 'upsert' :
9352 message .setdefault ('key_names' , self .key_names )
94- elif message ['action' ] == 'switch_view' :
95- pass
9653 else :
97- raise ValueError ('Message action property must be one of: "upsert", "switch_view "' )
54+ raise ValueError ('Message action property must be "upsert"' )
9855
9956 message ['client_id' ] = self .client_id
10057 message .setdefault ('table_name' , self .table_name )
@@ -104,7 +61,8 @@ def push(self, message, callback_arg = None):
10461 writer .write (message )
10562 self ._buffer .put (s .getvalue (), callback_arg )
10663
107- batch = self ._buffer .take (self .batch_size_bytes , self .batch_delay_millis )
64+ batch = self ._buffer .take (
65+ self .batch_size_bytes , self .batch_delay_millis )
10866 if batch is not None :
10967 self ._send_batch (batch )
11068
@@ -133,12 +91,12 @@ def _send_batch(self, batch):
13391 if self .callback_function is not None :
13492 self .callback_function ([x .callback_arg for x in batch ])
13593 else :
136- raise RuntimeError ("Error sending data to the Stitch API. {0.status_code} - {0.content}"
94+ raise RuntimeError ("Error sending data to the Stitch API. {0.status_code} - {0.content}" # nopep8
13795 .format (response ))
13896
13997 def flush (self ):
14098 while True :
141- batch = self ._buffer .take (0 ,0 )
99+ batch = self ._buffer .take (0 , 0 )
142100 if batch is None :
143101 return
144102
@@ -153,8 +111,10 @@ def __exit__(self, exception_type, exception_value, traceback):
153111if __name__ == "__main__" :
154112 logging .basicConfig (level = logging .DEBUG )
155113
156- with Client (int (os .environ ['STITCH_CLIENT_ID' ]), os .environ ['STITCH_TOKEN' ], callback_function = print ) as c :
157- for i in range (1 ,10 ):
114+ with Client (int (os .environ ['STITCH_CLIENT_ID' ]),
115+ os .environ ['STITCH_TOKEN' ],
116+ callback_function = print ) as c :
117+ for i in range (1 , 10 ):
158118 c .push ({'action' : 'upsert' ,
159119 'table_name' : 'test_table' ,
160120 'key_names' : ['id' ],
0 commit comments