Persistence with db
Browse files- .gitignore +4 -1
- __pycache__/dropbox_handler.cpython-311.pyc +0 -0
- __pycache__/dropbox_trial.cpython-311.pyc +0 -0
- __pycache__/firebase_handler.cpython-311.pyc +0 -0
- dropbox_handler.py +148 -0
- firebase_handler.py +21 -0
- main.py +7 -2
- requirements.txt +1 -0
.gitignore
CHANGED
|
@@ -1,2 +1,5 @@
|
|
| 1 |
indexer_local.py
|
| 2 |
-
retrival_local.py
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
indexer_local.py
|
| 2 |
+
retrival_local.py
|
| 3 |
+
dropbox_trial.py
|
| 4 |
+
commandline-oauth-scope.py
|
| 5 |
+
*.ipynb
|
__pycache__/dropbox_handler.cpython-311.pyc
ADDED
|
Binary file (7.78 kB). View file
|
|
|
__pycache__/dropbox_trial.cpython-311.pyc
ADDED
|
Binary file (7.13 kB). View file
|
|
|
__pycache__/firebase_handler.cpython-311.pyc
ADDED
|
Binary file (1.22 kB). View file
|
|
|
dropbox_handler.py
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import datetime
|
| 2 |
+
import time
|
| 3 |
+
import dropbox
|
| 4 |
+
from dropbox.files import WriteMode
|
| 5 |
+
from dropbox.exceptions import ApiError, AuthError
|
| 6 |
+
import sys,os
|
| 7 |
+
import firebase_handler as fbh
|
| 8 |
+
|
| 9 |
+
TOKEN=fbh.fb_get("d2_accesstoken")
|
| 10 |
+
APP_KEY=os.environ['DROPBOX_APP_KEY']
|
| 11 |
+
APP_SECRET=os.environ['DROPBOX_APP_SECRET']
|
| 12 |
+
REFRESH_TOKEN=fbh.fb_get("d2_refreshtoken")
|
| 13 |
+
|
| 14 |
+
#os.environ['DROP_DIR2']="C:/dockers/chroma/chroma1/"
|
| 15 |
+
#os.environ['APP_PATH']="/"
|
| 16 |
+
print("token::",TOKEN)
|
| 17 |
+
|
| 18 |
+
with dropbox.Dropbox(oauth2_access_token=TOKEN,app_key=APP_KEY,app_secret=APP_SECRET,oauth2_refresh_token=REFRESH_TOKEN) as dbx: #,app_key=APP_KEY,app_secret=APP_SECRET,oauth2_refresh_token=REFRESH_TOKEN) as dbx:
|
| 19 |
+
# Check that the access token is valid
|
| 20 |
+
try:
|
| 21 |
+
dbx.users_get_current_account()
|
| 22 |
+
except AuthError:
|
| 23 |
+
try:
|
| 24 |
+
dbx.check_and_refresh_access_token()
|
| 25 |
+
fbh.fb_update("d2_accesstoken",dbx._oauth2_access_token)
|
| 26 |
+
except Exception:
|
| 27 |
+
sys.exit("ERROR: Invalid access token; try re-generating an "
|
| 28 |
+
"access token from the app console on the web.")
|
| 29 |
+
|
| 30 |
+
def normalizeFilename(filename):
|
| 31 |
+
while '//' in filename:
|
| 32 |
+
filename = filename.replace('//', '/')
|
| 33 |
+
return filename
|
| 34 |
+
|
| 35 |
+
def getDropboxFilename(localFilename):
|
| 36 |
+
""" localFilename is $DROP_DIR2/<subpath>/<filename>"""
|
| 37 |
+
""" dropboxFilename is $APP_PATH/<subpath>/<filename"""
|
| 38 |
+
localFilename=normalizeFilename(localFilename)
|
| 39 |
+
return normalizeFilename(localFilename.replace(os.environ['DROP_DIR2'],"/",1).replace("/",os.environ['APP_PATH'],1))
|
| 40 |
+
|
| 41 |
+
def getLocalFilename(dropboxFilename):
|
| 42 |
+
""" localFilename is $DROP_DIR2/<subpath>/<filename>"""
|
| 43 |
+
""" dropboxFilename is $APP_PATH/<subpath>/<filename"""
|
| 44 |
+
dropboxFilename=normalizeFilename(dropboxFilename)
|
| 45 |
+
return normalizeFilename(dropboxFilename.replace(os.environ['APP_PATH'],"/",1).replace("/",os.environ['DROP_DIR2'],1))
|
| 46 |
+
|
| 47 |
+
def backupFile(localFilename):
|
| 48 |
+
"""Upload a file.
|
| 49 |
+
Return the request response, or None in case of error.
|
| 50 |
+
This will also create directory on dropbox if needed
|
| 51 |
+
"""
|
| 52 |
+
localFilename=normalizeFilename(localFilename)
|
| 53 |
+
dropboxFilename=getDropboxFilename(localFilename)
|
| 54 |
+
mode = dropbox.files.WriteMode.overwrite
|
| 55 |
+
mtime = os.path.getmtime(localFilename)
|
| 56 |
+
with open(localFilename, 'rb') as f:
|
| 57 |
+
data = f.read()
|
| 58 |
+
try:
|
| 59 |
+
res = dbx.files_upload(
|
| 60 |
+
data, dropboxFilename, mode,
|
| 61 |
+
client_modified=datetime.datetime(*time.gmtime(mtime)[:6]),
|
| 62 |
+
mute=True)
|
| 63 |
+
except dropbox.exceptions.ApiError as err:
|
| 64 |
+
print('*** API error', err)
|
| 65 |
+
return None
|
| 66 |
+
print('uploaded as', res.name.encode('utf8'))
|
| 67 |
+
return res
|
| 68 |
+
|
| 69 |
+
def restoreFile(dropboxFilename):
|
| 70 |
+
"""Download a file.
|
| 71 |
+
Return the bytes of the file, or None if it doesn't exist.
|
| 72 |
+
Will create dir+subdirs if possible
|
| 73 |
+
"""
|
| 74 |
+
dropboxFilename=normalizeFilename(dropboxFilename)
|
| 75 |
+
localFilename=getLocalFilename(dropboxFilename)
|
| 76 |
+
try:
|
| 77 |
+
md, res = dbx.files_download(dropboxFilename)
|
| 78 |
+
except dropbox.exceptions.HttpError as err:
|
| 79 |
+
print('*** HTTP error', err)
|
| 80 |
+
return None
|
| 81 |
+
data = res.content
|
| 82 |
+
print(len(data), 'bytes; md:', md)
|
| 83 |
+
localdir=os.path.dirname(localFilename)
|
| 84 |
+
if not os.path.exists(localdir):
|
| 85 |
+
os.makedirs(localdir)
|
| 86 |
+
with open(localFilename, 'wb') as f:
|
| 87 |
+
f.write(data)
|
| 88 |
+
return data
|
| 89 |
+
|
| 90 |
+
def backupFolder(localFolder):
|
| 91 |
+
""" list all files in folder and subfolder and upload them"""
|
| 92 |
+
filenames=[]
|
| 93 |
+
for (root,dirs,files) in os.walk(localFolder, topdown=True):
|
| 94 |
+
print(root)
|
| 95 |
+
for filename in files:
|
| 96 |
+
filenames.append(root+"/"+filename)
|
| 97 |
+
print(root+"/"+filename)
|
| 98 |
+
backupFile(root+"/"+filename)
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
def restoreFolder(dropboxFolder):
|
| 102 |
+
""" list all files in dropbox folder and subfolders and restore them"""
|
| 103 |
+
try:
|
| 104 |
+
res=dbx.files_list_folder(dropboxFolder)
|
| 105 |
+
except dropbox.exceptions.ApiError as err:
|
| 106 |
+
print('Folder listing failed for', dropboxFolder, '-- assumed empty:', err)
|
| 107 |
+
for entry in res.entries:
|
| 108 |
+
if (isinstance(entry, dropbox.files.FileMetadata)):
|
| 109 |
+
restoreFile(entry.path_display)
|
| 110 |
+
else:
|
| 111 |
+
try:
|
| 112 |
+
restoreFolder(entry.path_display)
|
| 113 |
+
except Exception:
|
| 114 |
+
print("Error restoring folder,",entry.path_display)
|
| 115 |
+
print(entry.path_display)
|
| 116 |
+
#TODO: If entry is FileMeta type then get the path_display and call restoreFile
|
| 117 |
+
#TODO: 2 If entry is FolderMeta type then call this function recursively fot it's path_display
|
| 118 |
+
#restoreFile(entry)
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
# def backup(localfile,dropbox_file):
|
| 122 |
+
# with open(localfile, 'rb') as f:
|
| 123 |
+
# # We use WriteMode=overwrite to make sure that the settings in the file
|
| 124 |
+
# # are changed on upload
|
| 125 |
+
# print("Uploading " + localfile + " to Dropbox as " + dropbox_file + "...")
|
| 126 |
+
# try:
|
| 127 |
+
# dbx.files_upload(f.read(), dropbox_file, mode=WriteMode('overwrite'))
|
| 128 |
+
# except ApiError as err:
|
| 129 |
+
# # This checks for the specific error where a user doesn't have
|
| 130 |
+
# # enough Dropbox space quota to upload this file
|
| 131 |
+
# if (err.error.is_path() and
|
| 132 |
+
# err.error.get_path().reason.is_insufficient_space()):
|
| 133 |
+
# sys.exit("ERROR: Cannot back up; insufficient space.")
|
| 134 |
+
# elif err.user_message_text:
|
| 135 |
+
# print(err.user_message_text)
|
| 136 |
+
# sys.exit()
|
| 137 |
+
# else:
|
| 138 |
+
# print(err)
|
| 139 |
+
# sys.exit()
|
| 140 |
+
|
| 141 |
+
# def restore(dropbox_file,localfile):
|
| 142 |
+
# Restore the file on Dropbox to a certain revision
|
| 143 |
+
#print("Restoring " + BACKUPPATH + " to revision " + rev + " on Dropbox...")
|
| 144 |
+
#dbx.files_restore(BACKUPPATH, rev)
|
| 145 |
+
|
| 146 |
+
# Download the specific revision of the file at BACKUPPATH to LOCALFILE
|
| 147 |
+
#print("Downloading current " + BACKUPPATH + " from Dropbox, overwriting " + LOCALFILE + "...")
|
| 148 |
+
#dbx.files_download_to_file(LOCALFILE, BACKUPPATH, rev)
|
firebase_handler.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from firebase import firebase
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
secret=os.environ['FIREBASE_TOKEN']
|
| 5 |
+
user_id="123"
|
| 6 |
+
auth=firebase.FirebaseAuthentication(secret=secret,email="anubhav77@gmail.com",extra={"id":user_id})
|
| 7 |
+
fb_url="https://device-1a455.firebaseio.com"
|
| 8 |
+
fb= firebase.FirebaseApplication(fb_url,auth)
|
| 9 |
+
base_dir="/users/"+user_id
|
| 10 |
+
|
| 11 |
+
def fb_get(item):
|
| 12 |
+
""" item need to be in format d2_refreshtoken same name will be present in the firebase
|
| 13 |
+
d2 means second dropbox instance or app.
|
| 14 |
+
"""
|
| 15 |
+
return fb.get(base_dir,item)
|
| 16 |
+
|
| 17 |
+
def fb_update(item,value):
|
| 18 |
+
""" item need to be in format d2_refreshtoken same name will be present in the firebase
|
| 19 |
+
d2 means second dropbox instance or app.
|
| 20 |
+
"""
|
| 21 |
+
return fb.patch(base_dir,{item:value})
|
main.py
CHANGED
|
@@ -52,6 +52,7 @@ import chromadb.errors as errors
|
|
| 52 |
from uuid import UUID
|
| 53 |
from chromadb.telemetry import Telemetry
|
| 54 |
from overrides import override
|
|
|
|
| 55 |
|
| 56 |
async def catch_exceptions_middleware(
|
| 57 |
request: Request, call_next: Callable[[Request], Any]
|
|
@@ -73,7 +74,7 @@ def _uuid(uuid_str: str) -> UUID:
|
|
| 73 |
except ValueError:
|
| 74 |
raise InvalidUUIDError(f"Could not parse {uuid_str} as a UUID")
|
| 75 |
|
| 76 |
-
|
| 77 |
app = fastapi.FastAPI(title="ChromaDB")
|
| 78 |
app.middleware("http")(catch_exceptions_middleware)
|
| 79 |
app.add_middleware(
|
|
@@ -102,6 +103,7 @@ def read_info(request: Request):
|
|
| 102 |
request_method = request.method
|
| 103 |
request_headers = request.headers
|
| 104 |
request_body = request.body
|
|
|
|
| 105 |
response= JSONResponse(content= {"nanosecond heartbeat":int(time.time_ns())})
|
| 106 |
response.set_cookie(key="my_cookie", value="12345", httponly=True, secure=True)
|
| 107 |
return response
|
|
@@ -109,6 +111,7 @@ def read_info(request: Request):
|
|
| 109 |
@app.post(api_base+"/reset")
|
| 110 |
def reset():
|
| 111 |
print("Received reset request")
|
|
|
|
| 112 |
return bkend.reset()
|
| 113 |
|
| 114 |
@app.get(api_base+"/version")
|
|
@@ -119,7 +122,9 @@ def version():
|
|
| 119 |
@app.post(api_base+"/persist")
|
| 120 |
def persist():
|
| 121 |
print("Received persist request")
|
| 122 |
-
|
|
|
|
|
|
|
| 123 |
|
| 124 |
@app.post(api_base+"/raw_sql")
|
| 125 |
def raw_sql(raw_sql: RawSql):
|
|
|
|
| 52 |
from uuid import UUID
|
| 53 |
from chromadb.telemetry import Telemetry
|
| 54 |
from overrides import override
|
| 55 |
+
import dropbox_handler as dbh
|
| 56 |
|
| 57 |
async def catch_exceptions_middleware(
|
| 58 |
request: Request, call_next: Callable[[Request], Any]
|
|
|
|
| 74 |
except ValueError:
|
| 75 |
raise InvalidUUIDError(f"Could not parse {uuid_str} as a UUID")
|
| 76 |
|
| 77 |
+
dbh.restoreFolder("./index/chroma")
|
| 78 |
app = fastapi.FastAPI(title="ChromaDB")
|
| 79 |
app.middleware("http")(catch_exceptions_middleware)
|
| 80 |
app.add_middleware(
|
|
|
|
| 103 |
request_method = request.method
|
| 104 |
request_headers = request.headers
|
| 105 |
request_body = request.body
|
| 106 |
+
print(request_headers)
|
| 107 |
response= JSONResponse(content= {"nanosecond heartbeat":int(time.time_ns())})
|
| 108 |
response.set_cookie(key="my_cookie", value="12345", httponly=True, secure=True)
|
| 109 |
return response
|
|
|
|
| 111 |
@app.post(api_base+"/reset")
|
| 112 |
def reset():
|
| 113 |
print("Received reset request")
|
| 114 |
+
dbh.restoreFolder("./index/chroma")
|
| 115 |
return bkend.reset()
|
| 116 |
|
| 117 |
@app.get(api_base+"/version")
|
|
|
|
| 122 |
@app.post(api_base+"/persist")
|
| 123 |
def persist():
|
| 124 |
print("Received persist request")
|
| 125 |
+
retVal=bkend.persist()
|
| 126 |
+
dbh.backupFolder("./index/chroma")
|
| 127 |
+
return retVal
|
| 128 |
|
| 129 |
@app.post(api_base+"/raw_sql")
|
| 130 |
def raw_sql(raw_sql: RawSql):
|
requirements.txt
CHANGED
|
@@ -9,3 +9,4 @@ langchain
|
|
| 9 |
sentence_transformers
|
| 10 |
sse_starlette
|
| 11 |
dropbox
|
|
|
|
|
|
| 9 |
sentence_transformers
|
| 10 |
sse_starlette
|
| 11 |
dropbox
|
| 12 |
+
firebase
|