eshan6704 commited on
Commit
64cf050
·
verified ·
1 Parent(s): f094bae

Upload persist.py

Browse files
Files changed (1) hide show
  1. app/persist/persist.py +149 -0
app/persist/persist.py ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import pickle
4
+ import pandas as pd
5
+ from datetime import datetime
6
+ from typing import Any
7
+
8
+ # ==============================
9
+ # Configuration
10
+ # ==============================
11
+ BASE_DIR = "./data/store"
12
+ os.makedirs(BASE_DIR, exist_ok=True)
13
+
14
+ IMAGE_TYPES = {"png", "jpg", "jpeg"}
15
+
16
+ # ==============================
17
+ # Helpers
18
+ # ==============================
19
+ def _ts():
20
+ return datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
21
+
22
+ def _path(filename: str):
23
+ return os.path.join(BASE_DIR, filename)
24
+
25
+ def _list_files():
26
+ return os.listdir(BASE_DIR)
27
+
28
+ def _latest(prefix: str, ext: str):
29
+ files = [
30
+ f for f in _list_files()
31
+ if f.startswith(prefix + "_") and f.endswith("." + ext)
32
+ ]
33
+ return max(files) if files else None
34
+
35
+ # ==============================
36
+ # Save
37
+ # ==============================
38
+ def save(name: str, data: Any, ftype: str, timestamped=True) -> bool:
39
+ """
40
+ name: base filename without extension
41
+ ftype: html, json, csv, pkl, png, jpg, jpeg
42
+ timestamped: False for stable assets like images
43
+ """
44
+ try:
45
+ if ftype in IMAGE_TYPES:
46
+ filename = f"{name}.{ftype}"
47
+ else:
48
+ ts = _ts() if timestamped else ""
49
+ filename = f"{name}_{ts}.{ftype}" if ts else f"{name}.{ftype}"
50
+
51
+ path = _path(filename)
52
+
53
+ if ftype == "csv":
54
+ if not isinstance(data, pd.DataFrame):
55
+ raise ValueError("CSV requires pandas DataFrame")
56
+ data.to_csv(path, index=False)
57
+
58
+ elif ftype == "json":
59
+ with open(path, "w", encoding="utf-8") as f:
60
+ json.dump(data, f, indent=2)
61
+
62
+ elif ftype == "html":
63
+ with open(path, "w", encoding="utf-8") as f:
64
+ f.write(str(data))
65
+
66
+ elif ftype in IMAGE_TYPES:
67
+ # data can be bytes or a file path
68
+ if isinstance(data, (bytes, bytearray)):
69
+ with open(path, "wb") as f:
70
+ f.write(data)
71
+ elif isinstance(data, str) and os.path.exists(data):
72
+ with open(data, "rb") as src, open(path, "wb") as dst:
73
+ dst.write(src.read())
74
+ else:
75
+ raise ValueError("Image data must be bytes or file path")
76
+
77
+ elif ftype == "pkl":
78
+ with open(path, "wb") as f:
79
+ pickle.dump(data, f)
80
+
81
+ else:
82
+ raise ValueError(f"Unsupported file type: {ftype}")
83
+
84
+ print(f"[SAVE OK] {filename}")
85
+ return True
86
+
87
+ except Exception as e:
88
+ print(f"[SAVE FAILED] {name}.{ftype} → {e}")
89
+ return False
90
+
91
+ # ==============================
92
+ # Load
93
+ # ==============================
94
+ def load(name: str, ftype: str):
95
+ filename = name if "." in name else _latest(name, ftype)
96
+ if not filename:
97
+ return False
98
+
99
+ path = _path(filename)
100
+ if not os.path.exists(path):
101
+ return False
102
+
103
+ try:
104
+ if filename.endswith(".csv"):
105
+ return pd.read_csv(path)
106
+
107
+ if filename.endswith(".json"):
108
+ with open(path, "r", encoding="utf-8") as f:
109
+ return json.load(f)
110
+
111
+ if filename.endswith(".html"):
112
+ with open(path, "r", encoding="utf-8") as f:
113
+ return f.read()
114
+
115
+ if filename.endswith(tuple(IMAGE_TYPES)):
116
+ with open(path, "rb") as f:
117
+ return f.read()
118
+
119
+ if filename.endswith(".pkl"):
120
+ with open(path, "rb") as f:
121
+ return pickle.load(f)
122
+
123
+ except Exception as e:
124
+ print(f"[LOAD FAILED] {filename} → {e}")
125
+ return False
126
+
127
+ # ==============================
128
+ # Exists (NO TTL)
129
+ # ==============================
130
+ def exists(name: str, ftype: str) -> bool:
131
+ if ftype in IMAGE_TYPES:
132
+ return os.path.exists(_path(f"{name}.{ftype}"))
133
+
134
+ filename = _latest(name, ftype)
135
+ if not filename:
136
+ return False
137
+
138
+ return os.path.exists(_path(filename))
139
+
140
+ # ==============================
141
+ # List
142
+ # ==============================
143
+ def list_files(name=None, ftype=None):
144
+ files = sorted(_list_files())
145
+ if name:
146
+ files = [f for f in files if f.startswith(name)]
147
+ if ftype:
148
+ files = [f for f in files if f.endswith("." + ftype)]
149
+ return files