banko-ai-assistant 1.0.8__py3-none-any.whl → 1.0.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- banko_ai/vector_search/generator.py +110 -48
- {banko_ai_assistant-1.0.8.dist-info → banko_ai_assistant-1.0.9.dist-info}/METADATA +1 -1
- {banko_ai_assistant-1.0.8.dist-info → banko_ai_assistant-1.0.9.dist-info}/RECORD +7 -7
- {banko_ai_assistant-1.0.8.dist-info → banko_ai_assistant-1.0.9.dist-info}/WHEEL +0 -0
- {banko_ai_assistant-1.0.8.dist-info → banko_ai_assistant-1.0.9.dist-info}/entry_points.txt +0 -0
- {banko_ai_assistant-1.0.8.dist-info → banko_ai_assistant-1.0.9.dist-info}/licenses/LICENSE +0 -0
- {banko_ai_assistant-1.0.8.dist-info → banko_ai_assistant-1.0.9.dist-info}/top_level.txt +0 -0
@@ -224,56 +224,118 @@ class EnhancedExpenseGenerator:
|
|
224
224
|
return expenses
|
225
225
|
|
226
226
|
def save_expenses_to_database(self, expenses: List[Dict[str, Any]]) -> int:
|
227
|
-
"""Save expenses to the database."""
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
227
|
+
"""Save expenses to the database with retry logic for CockroachDB."""
|
228
|
+
import pandas as pd
|
229
|
+
import time
|
230
|
+
import random
|
231
|
+
from sqlalchemy.exc import OperationalError
|
232
|
+
|
233
|
+
# Prepare data for insertion
|
234
|
+
data_to_insert = []
|
235
|
+
for expense in expenses:
|
236
|
+
data_to_insert.append({
|
237
|
+
'expense_id': expense['expense_id'],
|
238
|
+
'user_id': expense['user_id'],
|
239
|
+
'expense_date': expense['expense_date'],
|
240
|
+
'expense_amount': expense['expense_amount'],
|
241
|
+
'shopping_type': expense['shopping_type'],
|
242
|
+
'description': expense['description'],
|
243
|
+
'merchant': expense['merchant'],
|
244
|
+
'payment_method': expense['payment_method'],
|
245
|
+
'recurring': expense['recurring'],
|
246
|
+
'tags': expense['tags'],
|
247
|
+
'embedding': expense['embedding']
|
248
|
+
})
|
249
|
+
|
250
|
+
# Insert in smaller batches to reduce transaction conflicts
|
251
|
+
batch_size = 50 # Reduced from 100 to minimize conflicts
|
252
|
+
total_inserted = 0
|
253
|
+
|
254
|
+
for i in range(0, len(data_to_insert), batch_size):
|
255
|
+
batch = data_to_insert[i:i + batch_size]
|
256
|
+
|
257
|
+
# Retry logic for CockroachDB transaction conflicts
|
258
|
+
max_retries = 5
|
259
|
+
retry_count = 0
|
260
|
+
|
261
|
+
while retry_count < max_retries:
|
262
|
+
try:
|
263
|
+
with self.engine.connect() as conn:
|
264
|
+
# Use pandas to insert the batch
|
265
|
+
df = pd.DataFrame(batch)
|
266
|
+
df.to_sql('expenses', conn, if_exists='append', index=False, method='multi')
|
267
|
+
conn.commit()
|
268
|
+
total_inserted += len(batch)
|
269
|
+
break # Success, exit retry loop
|
270
|
+
|
271
|
+
except OperationalError as e:
|
272
|
+
# Check if it's a CockroachDB serialization failure (SQL state 40001)
|
273
|
+
if "40001" in str(e) or "SerializationFailure" in str(e) or "restart transaction" in str(e).lower():
|
274
|
+
retry_count += 1
|
275
|
+
if retry_count < max_retries:
|
276
|
+
# Exponential backoff with jitter
|
277
|
+
base_delay = 0.1 * (2 ** retry_count)
|
278
|
+
jitter = random.uniform(0, 0.1)
|
279
|
+
delay = base_delay + jitter
|
280
|
+
print(f"Transaction conflict detected, retrying in {delay:.2f}s (attempt {retry_count}/{max_retries})")
|
281
|
+
time.sleep(delay)
|
282
|
+
continue
|
283
|
+
else:
|
284
|
+
print(f"Max retries exceeded for batch {i//batch_size + 1}: {e}")
|
285
|
+
return total_inserted
|
286
|
+
else:
|
287
|
+
# Non-retryable error
|
288
|
+
print(f"Non-retryable database error: {e}")
|
289
|
+
return total_inserted
|
290
|
+
|
291
|
+
except Exception as e:
|
292
|
+
print(f"Unexpected error saving batch {i//batch_size + 1}: {e}")
|
293
|
+
return total_inserted
|
294
|
+
|
295
|
+
return total_inserted
|
265
296
|
|
266
297
|
def clear_expenses(self) -> bool:
|
267
|
-
"""Clear all expenses from the database."""
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
298
|
+
"""Clear all expenses from the database with retry logic."""
|
299
|
+
import time
|
300
|
+
import random
|
301
|
+
from sqlalchemy import text
|
302
|
+
from sqlalchemy.exc import OperationalError
|
303
|
+
|
304
|
+
max_retries = 5
|
305
|
+
retry_count = 0
|
306
|
+
|
307
|
+
while retry_count < max_retries:
|
308
|
+
try:
|
309
|
+
with self.engine.connect() as conn:
|
310
|
+
conn.execute(text("DELETE FROM expenses"))
|
311
|
+
conn.commit()
|
312
|
+
return True
|
313
|
+
|
314
|
+
except OperationalError as e:
|
315
|
+
# Check if it's a CockroachDB serialization failure (SQL state 40001)
|
316
|
+
if "40001" in str(e) or "SerializationFailure" in str(e) or "restart transaction" in str(e).lower():
|
317
|
+
retry_count += 1
|
318
|
+
if retry_count < max_retries:
|
319
|
+
# Exponential backoff with jitter
|
320
|
+
base_delay = 0.1 * (2 ** retry_count)
|
321
|
+
jitter = random.uniform(0, 0.1)
|
322
|
+
delay = base_delay + jitter
|
323
|
+
print(f"Transaction conflict detected while clearing, retrying in {delay:.2f}s (attempt {retry_count}/{max_retries})")
|
324
|
+
time.sleep(delay)
|
325
|
+
continue
|
326
|
+
else:
|
327
|
+
print(f"Max retries exceeded while clearing expenses: {e}")
|
328
|
+
return False
|
329
|
+
else:
|
330
|
+
# Non-retryable error
|
331
|
+
print(f"Non-retryable database error while clearing: {e}")
|
332
|
+
return False
|
333
|
+
|
334
|
+
except Exception as e:
|
335
|
+
print(f"Unexpected error clearing expenses: {e}")
|
336
|
+
return False
|
337
|
+
|
338
|
+
return False
|
277
339
|
|
278
340
|
def get_expense_count(self) -> int:
|
279
341
|
"""Get the current number of expenses in the database."""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: banko-ai-assistant
|
3
|
-
Version: 1.0.
|
3
|
+
Version: 1.0.9
|
4
4
|
Summary: AI-powered expense analysis and RAG system with CockroachDB vector search and multi-provider AI support
|
5
5
|
Author-email: Virag Tripathi <virag.tripathi@gmail.com>
|
6
6
|
License-Expression: MIT
|
@@ -151,14 +151,14 @@ banko_ai/utils/database.py,sha256=sJYAFTApkWReEJuMbbBDiz7XfgiiEd6lPSSyF6BQDpk,77
|
|
151
151
|
banko_ai/utils/migration.py,sha256=j1lYUVZyYMcMvxZUOFymoK19QTPqkDZFXD-iysVCnQo,4764
|
152
152
|
banko_ai/vector_search/__init__.py,sha256=vYksnkUU4FA8XBNzYZIH4FoGjXCx9oIbrDeapSzrNuE,621
|
153
153
|
banko_ai/vector_search/enrichment.py,sha256=sRnFLNG9WGfq8j44T7krxHI-Lc2RSH68mt0IT0GTHBA,10203
|
154
|
-
banko_ai/vector_search/generator.py,sha256=
|
154
|
+
banko_ai/vector_search/generator.py,sha256=l5DdeAiPBHLkbMnFvX03rTSn4b9JS2jiP_Pf_A6Lxpk,16437
|
155
155
|
banko_ai/vector_search/search.py,sha256=k3wo3zFJH9o-kBc-vAS-bdmM3LGX2vIk3u4cRA5QPXo,16915
|
156
156
|
banko_ai/web/__init__.py,sha256=hjWVVxYpIZhOAN1qBf4xTd36a5AUHM03Q8BF8pykhJQ,363
|
157
157
|
banko_ai/web/app.py,sha256=9xBe6RsyEUQvpDhsRckJ4pzk5x2RZWEhVs8DiJg4zqs,27675
|
158
158
|
banko_ai/web/auth.py,sha256=js6qIixSFHyLbETDm8GNLCPrDkCDcaQZPFOrqtZP1uw,2125
|
159
|
-
banko_ai_assistant-1.0.
|
160
|
-
banko_ai_assistant-1.0.
|
161
|
-
banko_ai_assistant-1.0.
|
162
|
-
banko_ai_assistant-1.0.
|
163
|
-
banko_ai_assistant-1.0.
|
164
|
-
banko_ai_assistant-1.0.
|
159
|
+
banko_ai_assistant-1.0.9.dist-info/licenses/LICENSE,sha256=skG0LkywIClj8fgSIXiG6o9vUDJ678BKBObIyJ19OMw,1075
|
160
|
+
banko_ai_assistant-1.0.9.dist-info/METADATA,sha256=fRuFpSdfmLnibvN9_9DAN-AyTDY6a2hTsAIFOp2E1wc,13243
|
161
|
+
banko_ai_assistant-1.0.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
162
|
+
banko_ai_assistant-1.0.9.dist-info/entry_points.txt,sha256=IxPjBjMvbpCp-ikCA43bOSbYboTGPX4HYcZlvu2_vcA,47
|
163
|
+
banko_ai_assistant-1.0.9.dist-info/top_level.txt,sha256=xNMa9Z67UssefOQ2ubFObtqUYIfYmCIclfz0xdo5OPE,9
|
164
|
+
banko_ai_assistant-1.0.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|