amauricunha commited on
Commit
a21486e
·
verified ·
1 Parent(s): 50ea5f1

Upload 5 files

Browse files
Files changed (1) hide show
  1. flask_app_hf.py +84 -85
flask_app_hf.py CHANGED
@@ -377,7 +377,8 @@ def system_status():
377
  'groq': groq_client is not None,
378
  'gemini': genai_client is not None
379
  },
380
- 'storage': 'file_based',
 
381
  'auth': 'disabled'
382
  })
383
 
@@ -388,30 +389,26 @@ def admin_system_health():
388
  """Return simple system health info using file-based storage (no external deps)."""
389
  try:
390
  import shutil
391
- data_root = DATA_ROOT
392
  schema = {}
393
  total_rows = 0
394
  db_size = 0
395
 
396
- if os.path.exists(data_root):
397
- for folder in os.listdir(data_root):
398
- folder_path = os.path.join(data_root, folder)
399
- if os.path.isdir(folder_path):
400
- files = [f for f in os.listdir(folder_path) if f.endswith('.json')]
401
- row_count = len(files)
402
- total_rows += row_count
403
- # approximate size
404
- size = 0
405
- for fn in files:
406
- p = os.path.join(folder_path, fn)
407
- try:
408
- size += os.path.getsize(p)
409
- except Exception:
410
- pass
411
- db_size += size
412
- schema[folder] = {'row_count': row_count, 'size_bytes': size}
413
-
414
- # disk usage for current filesystem
415
  try:
416
  du = shutil.disk_usage('.')
417
  disk = {
@@ -424,10 +421,10 @@ def admin_system_health():
424
  disk = {}
425
 
426
  health = {
427
- 'memory': None,
428
  'disk': disk,
429
  'database': {
430
- 'data_root': data_root,
431
  'total_rows': total_rows,
432
  'estimated_size_bytes': db_size,
433
  'tables': schema
@@ -445,36 +442,33 @@ def admin_system_health():
445
  def admin_database_schema():
446
  """Return a simple schema overview derived from hf_data folders."""
447
  try:
448
- data_root = DATA_ROOT
449
  schema = {}
450
- if os.path.exists(data_root):
451
- for folder in os.listdir(data_root):
452
- folder_path = os.path.join(data_root, folder)
453
- if os.path.isdir(folder_path):
454
- files = [f for f in os.listdir(folder_path) if f.endswith('.json')]
455
- # try to infer columns from first file
 
 
 
 
 
 
 
 
 
 
 
 
 
456
  cols = []
457
- if files:
458
- sample_path = os.path.join(folder_path, files[0])
459
- try:
460
- with open(sample_path, 'r', encoding='utf-8') as fh:
461
- data = json.load(fh)
462
- if isinstance(data, list) and data:
463
- sample = data[0]
464
- elif isinstance(data, dict):
465
- sample = data
466
- else:
467
- sample = {}
468
- cols = [{'name': k, 'type': type(v).__name__} for k, v in (sample or {}).items()]
469
- except Exception:
470
- cols = []
471
 
472
- schema[folder] = {
473
- 'row_count': len(files),
474
- 'columns': cols
475
- }
476
- else:
477
- schema = {}
478
 
479
  return jsonify({'success': True, 'schema': schema})
480
  except Exception as e:
@@ -502,21 +496,12 @@ def admin_list_users():
502
  flashcards = len(load_user_data(uid, 'flashcards'))
503
  conversations = len(load_user_data(uid, 'conversations'))
504
  analytics = len(load_user_data(uid, 'analytics'))
505
-
506
- # estimate created_at by file mtime if available
507
  created_at = None
508
  try:
509
- path_candidates = [
510
- os.path.join(DATA_ROOT, 'flashcards', f"{uid}.json"),
511
- os.path.join(DATA_ROOT, 'conversations', f"{uid}.json"),
512
- os.path.join(DATA_ROOT, 'analytics', f"{uid}.json")
513
- ]
514
- mtimes = []
515
- for p in path_candidates:
516
- if os.path.exists(p):
517
- mtimes.append(os.path.getmtime(p))
518
- if mtimes:
519
- created_at = datetime.fromtimestamp(min(mtimes)).isoformat()
520
  except Exception:
521
  created_at = None
522
 
@@ -540,16 +525,22 @@ def admin_user_detail(user_id):
540
  """Get detailed info for a user or delete their data (file-based)."""
541
  try:
542
  if request.method == 'DELETE':
543
- # remove files across hf_data
544
  removed = []
545
- for folder in ['flashcards', 'conversations', 'analytics']:
546
- p = os.path.join(DATA_ROOT, folder, f"{user_id}.json")
547
  try:
548
- if os.path.exists(p):
549
- os.remove(p)
550
- removed.append(p)
 
551
  except Exception as ex:
552
- print(f"Failed deleting {p}: {ex}")
 
 
 
 
 
 
553
  return jsonify({'success': True, 'deleted': removed})
554
 
555
  # GET -> return analytics, flashcards, conversations
@@ -648,22 +639,30 @@ def admin_export_all():
648
  """Package the entire DATA_ROOT into a zip and send for download."""
649
  try:
650
  import zipfile
651
- import tempfile
652
-
653
- if not os.path.exists(DATA_ROOT):
654
- return jsonify({'success': False, 'error': 'No data directory found'}), 404
655
 
656
- tmp = tempfile.NamedTemporaryFile(delete=False, suffix='.zip')
657
- tmp.close()
658
-
659
- with zipfile.ZipFile(tmp.name, 'w', compression=zipfile.ZIP_DEFLATED) as zf:
660
- for root, dirs, files in os.walk(DATA_ROOT):
661
- for f in files:
662
- full = os.path.join(root, f)
663
- arcname = os.path.relpath(full, DATA_ROOT)
664
- zf.write(full, arcname)
665
-
666
- return send_file(tmp.name, mimetype='application/zip', as_attachment=True, download_name='hf_data_export.zip')
 
 
 
 
 
 
 
 
 
 
 
 
667
  except Exception as e:
668
  print(f"export all error: {e}")
669
  return jsonify({'success': False, 'error': str(e)}), 500
 
377
  'groq': groq_client is not None,
378
  'gemini': genai_client is not None
379
  },
380
+ 'storage': 'in_memory',
381
+ 'demo_mode': True,
382
  'auth': 'disabled'
383
  })
384
 
 
389
  """Return simple system health info using file-based storage (no external deps)."""
390
  try:
391
  import shutil
392
+ # compute simple stats from IN_MEMORY
393
  schema = {}
394
  total_rows = 0
395
  db_size = 0
396
 
397
+ for table, table_data in IN_MEMORY.items():
398
+ if isinstance(table_data, dict):
399
+ row_count = sum(1 for _ in table_data.keys())
400
+ # approximate size by serializing entries
401
+ size = 0
402
+ for k, v in table_data.items():
403
+ try:
404
+ size += len(json.dumps(v, ensure_ascii=False).encode('utf-8'))
405
+ except Exception:
406
+ pass
407
+ schema[table] = {'row_count': row_count, 'size_bytes': size}
408
+ total_rows += row_count
409
+ db_size += size
410
+
411
+ # disk usage for current filesystem (informational)
 
 
 
 
412
  try:
413
  du = shutil.disk_usage('.')
414
  disk = {
 
421
  disk = {}
422
 
423
  health = {
424
+ 'memory': True,
425
  'disk': disk,
426
  'database': {
427
+ 'storage': 'in_memory',
428
  'total_rows': total_rows,
429
  'estimated_size_bytes': db_size,
430
  'tables': schema
 
442
  def admin_database_schema():
443
  """Return a simple schema overview derived from hf_data folders."""
444
  try:
445
+ # derive schema from IN_MEMORY
446
  schema = {}
447
+ for table, table_data in IN_MEMORY.items():
448
+ cols = []
449
+ row_count = 0
450
+ if isinstance(table_data, dict):
451
+ row_count = sum(1 for _ in table_data.keys())
452
+ # infer columns/types from first value
453
+ try:
454
+ first_val = None
455
+ for v in table_data.values():
456
+ first_val = v
457
+ break
458
+ sample = None
459
+ if isinstance(first_val, list) and first_val:
460
+ sample = first_val[0]
461
+ elif isinstance(first_val, dict):
462
+ sample = first_val
463
+ if isinstance(sample, dict):
464
+ cols = [{'name': k, 'type': type(v).__name__} for k, v in sample.items()]
465
+ except Exception:
466
  cols = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
467
 
468
+ schema[table] = {
469
+ 'row_count': row_count,
470
+ 'columns': cols
471
+ }
 
 
472
 
473
  return jsonify({'success': True, 'schema': schema})
474
  except Exception as e:
 
496
  flashcards = len(load_user_data(uid, 'flashcards'))
497
  conversations = len(load_user_data(uid, 'conversations'))
498
  analytics = len(load_user_data(uid, 'analytics'))
499
+ # created_at from user record if available
 
500
  created_at = None
501
  try:
502
+ urec = IN_MEMORY.get('users', {}).get(uid)
503
+ if urec and isinstance(urec, dict):
504
+ created_at = urec.get('created_at')
 
 
 
 
 
 
 
 
505
  except Exception:
506
  created_at = None
507
 
 
525
  """Get detailed info for a user or delete their data (file-based)."""
526
  try:
527
  if request.method == 'DELETE':
528
+ # remove in-memory records across tables
529
  removed = []
530
+ for folder in ['flashcards', 'conversations', 'analytics', 'study_plans']:
 
531
  try:
532
+ tbl = IN_MEMORY.get(folder, {})
533
+ if user_id in tbl:
534
+ del tbl[user_id]
535
+ removed.append(f"{folder}/{user_id}")
536
  except Exception as ex:
537
+ print(f"Failed deleting in-memory {folder}/{user_id}: {ex}")
538
+ # remove user record
539
+ try:
540
+ if user_id in IN_MEMORY.get('users', {}):
541
+ del IN_MEMORY['users'][user_id]
542
+ except Exception:
543
+ pass
544
  return jsonify({'success': True, 'deleted': removed})
545
 
546
  # GET -> return analytics, flashcards, conversations
 
639
  """Package the entire DATA_ROOT into a zip and send for download."""
640
  try:
641
  import zipfile
 
 
 
 
642
 
643
+ mem_zip = io.BytesIO()
644
+ with zipfile.ZipFile(mem_zip, 'w', compression=zipfile.ZIP_DEFLATED) as zf:
645
+ # dump each table as files
646
+ for table, table_data in IN_MEMORY.items():
647
+ if isinstance(table_data, dict):
648
+ for uid, val in table_data.items():
649
+ try:
650
+ payload = json.dumps(val, ensure_ascii=False, indent=2)
651
+ except Exception:
652
+ payload = str(val)
653
+ arcname = os.path.join(table, f"{uid}.json")
654
+ zf.writestr(arcname, payload)
655
+ else:
656
+ # serialize whole object
657
+ try:
658
+ payload = json.dumps(table_data, ensure_ascii=False, indent=2)
659
+ except Exception:
660
+ payload = str(table_data)
661
+ arcname = f"{table}.json"
662
+ zf.writestr(arcname, payload)
663
+
664
+ mem_zip.seek(0)
665
+ return send_file(mem_zip, mimetype='application/zip', as_attachment=True, download_name='hf_data_export.zip')
666
  except Exception as e:
667
  print(f"export all error: {e}")
668
  return jsonify({'success': False, 'error': str(e)}), 500